home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Tools 2
/
Amiga Tools 2.iso
/
tex
/
macros
/
source
/
contrib
/
supported
/
feynmf
/
feynmf.dtx
(
.txt
)
< prev
next >
Wrap
LaTeX Document
|
1995-03-15
|
145KB
|
4,002 lines
% \iffalse % feynmf.dtx - Feynman diagrams with METAFONT for LaTeX(2e)
% Copyright (C) 1989, 1990, 1992-1995 by Thorsten.Ohl@Physik.TH-Darmstadt.de
% /home/sources/ohl/tex/thotex/feynmf/feynmf.dtx,v 1.10 1995/02/18 16:42:18 ohl Exp
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Feynmf is free software; you can redistribute it and/or modify it
% under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2, or (at your option)
% any later version.
% Feynmf is distributed in the hope that it will be useful, but
% WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \fi
%% \CheckSum{553}
%% \CharacterTable
%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%% Digits \0\1\2\3\4\5\6\7\8\9
%% Exclamation \! Double quote \" Hash (number) \#
%% Dollar \$ Percent \% Ampersand \&
%% Acute accent \' Left paren \( Right paren \)
%% Asterisk \* Plus \+ Comma \,
%% Minus \- Point \. Solidus \/
%% Colon \: Semicolon \; Less than \<
%% Equals \= Greater than \> Question mark \?
%% Commercial at \@ Left bracket \[ Backslash \\
%% Right bracket \] Circumflex \^ Underscore \_
%% Grave accent \` Left brace \{ Vertical bar \|
%% Right brace \} Tilde \~}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \MakeShortVerb{\|}
% \title{%
% \FMF: \\
% Drawing Feynman Diagrams \\
% with \LaTeX{} and \MF}
% \author{%
% Thorsten Ohl\thanks{e-mail:
% {\tt Thorsten.Ohl@Physik.TH-Darmstadt.de}}\\
% \hfil \\
% Technische Hochschule Darmstadt \\
% Schlo\ss gartenstr. 9 \\
% D-64289 Darmstadt \\
% Germany}
% \maketitle
% \begin{abstract}
% \FMF{} is a \LaTeX{} package for easy drawing of professional
% quality Feynman diagrams with \MF. \FMF{} lays out most
% diagrams satisfactorily from the structure of the graph without
% any need for manual intervention. Nevertheless all the power of
% \MF{} is available for the most obscure cases.
% \end{abstract}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section*{Copying}
% \FMF{} is free software; you can redistribute it and/or modify it
% under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2, or (at your option)
% any later version.
% \FMF{} is distributed in the hope that it will be useful, but
% \emph{without any warranty}; without even the implied warranty of
% \emph{merchantability} or \emph{fitness for a particular purpose}.
% See the GNU General Public License for more details.
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \tableofcontents
% \unitlength=1mm
% \begin{fmffile}{fmfsampl}
% \def\bottomfraction{0}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Introduction}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Purpose and scope}
% In recent years, \TeX\footnote{\TeX{} is a trademark of the American
% Mathematical Society.}~\cite{TeX}
% and \LaTeX\footnote{\LaTeX{} might be a trademark of Addison Wesley
% Publishing Company.}~\cite{LaTeX}
% have revolutionized the way
% we share information in theoretical physics (and other areas). Not
% only does \TeX{} provide typographical capabilities, which transcend
% those of commercial ``wordprocessors'' substantially, \TeX{} documents
% are also completely portable. Since implementations are available
% on essentially all computers in use in the community, documents can
% be shared without the usual restrictions of proprietary data
% formats. This has enabled us to collaborate on papers with
% colleagues on the other side of the globe, to replace the mailing of
% hard copy preprints by electronic transmission and to submit these
% papers electronically to the publisher.
% This portability comes with a price, though. \TeX{} (and \LaTeX)
% do not address the issue of graphical information, apart from the
% rudimentary (but very useful) capabilities of the \LaTeX{} |picture|
% environment and similar
% packages~\cite{LaTeX-Companion}, which provide line drawings like
% the one in figure~\ref{fig:flow}. As an de facto standard for the
% inclusion of more complex graphics has emerged the inclusion of
% PostScript~\footnote{PostScript is a trademark of Adobe Systems
% Inc.}
% files. The complete document can then
% be printed on any PostScript device.
% Still there are areas, where complementary approaches seem worth
% pursuing. In particular this is the case, if the graphical
% information is highly formalized, like the case at hand. Feynman
% diagrams are specified by their topology and the type of particles
% connecting the vertices. Thus a given diagram can be reproduced
% from a very concise specification, if the software is able to choose
% a reasonable layout (semi-)automatically.
% \MF\footnote{\MF{} is a trademark of Addison Wesley Publishing
% Company.}~\cite{MF}
% and \MP\footnote{John Hobby's \MP{} is a modified version of \MF{}
% which generates (encapsulated) PostScript output. \MP{} can be
% build trivially on top of the \texttt{web2c} version of \TeX{} and
% \MF{} for UNIX. Ports to other systems should be
% simple.}~\cite{MetaPost}
% appear to be the perfect tool for such a purpose, since
% \begin{enumerate}
% \item{} \MF{} is part of any (reasonable) \TeX{} installation, thus
% available to all potential users,
% \item{} both have very powerful graphics primitivs, which allow high
% quality output, and
% \item{} both have builtin linear algebra, which allows us to choose a
% layout automatically.
% \end{enumerate}
% Still, providing at least the basic interface in \LaTeX{} macros
% seems appropriate for boosting the acceptance among the less
% technically oriented parts of the audience. Thus
% \FMF\footnote{\FMF{} is not a trademark of anybody.}
% was conceived.
% \FMF{} supports \MF{} as well as \MP{} (under the names
% \texttt{feynmp.sty} and \texttt{feynmp.mp}).
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Relation to similar packages}
% Before we start, a couple of words about some complementary packages
% on the market are in order. First of all: I failed to do my
% homework and didn't try hard enough to find~\cite{hoenig} in a
% library. I'm sure that in there is a smarter way of returning
% information from \MF{} to \TeX{}. Those who don't know the
% literature are doomed to reinvent the wheel. But this isn't a
% scholarly work and reinventing the wheel was \emph{fun!}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Feynman}
% Micheal Levine's |feynman| package~\cite{levine} is
% implemented on top of the standard \LaTeX{} |picture|
% environment~\cite{LaTeX}. This makes it completely portable (no
% need for a correct \MF{} installation), but it requires manual
% layout and the graphics output is (though very useful) less than
% perfect.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Axodraw}
% Jos Vermaseren's |axodraw| package~\cite{axodraw} uses
% |\special|s to access PostScript primitives for drawing diagrams.
% This approach is inherently not portable (though the ubiquity of
% PostScript printers makes this a minor point) but at least as
% flexible as the present one. It still requires manual layout,
% though.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Mfpic}
% Last, but not least, I have to mention Thomas Leathrum's
% |mfpic|~\cite{mfpic}, which was the main inspiration for moving
% \FMF's user interface from \MF{} to \TeX. It might not have been
% unreasonable to design and implement \FMF{} as a package on top of
% |mfpic|\footnote{In fact a change in this direction would be rather
% easy.},
% But closer inspection shows that \FMF{} and |mfpic| are fairly
% orthogonal. |mfpic| is ideally suited for handling simple graphical
% building blocks in formally unconstrained contexts, a task which will
% be accomplished preferably by direct manual placement of objects.
% \FMF{} on the other hand works in the highly formal context of
% Feynman diagrams (or any other labeled graphs for that matter),
% which can be draw automatically from a \emph{specification}.
% It will of course be tempting to add more features from |mfpic|'s
% realm to \FMF{} in the future, but I will try to be conservative in
% that respect.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Historical note}
% This code has a rather long history\footnote{Which is a partial
% explanation, if not excuse, for its slightly incoherent structure.}.
% Most of the sections~\ref{sec:mf-basics}, \ref{sec:pictures},
% \ref{sec:shading}, and~\ref{sec:drawing} started in 1989 as
% |feynman.mf|, a library of \MF{} macros for drawing Feynman
% diagrams in my thesis. The layout had to be chossen completely
% manually, which required a long edit-process-preview cycle and made
% |feynman.mf| awkward to use.
% Nevertheless, it survived for five years without major
% modifications, only slight enhancements had been made. Early in
% 1994, I became aware of Thomas Leathrum's |mfpic|~\cite{mfpic}.
% This inspired me to shift the user interface from \MF{} to
% \LaTeX, because this allows a smoother blending of the \LaTeX{}
% |picture| environment with \FMF{}. While doing this and after
% having been taught by Tim Stelzer's and Bill Long's
% \texttt{MADGRAPH}~\cite{madgraph} that minimizing the length of the
% graph gives surprisingly good results for tree graphs\footnote{I had
% thought about this earlier myself, but foolishly discarded the idea.
% I didn't expect such a ``too simple'' method to give esthetically
% pleasing results for loop graphs, which were my main concern.}, I
% added the graph manipulation code in section~\ref{sec:graphs}.
% And, of course, \FMF{} is biased towards those kinds of graphs that
% my students, my colleagues and myself have to draw most often.
% Comments for improvements from other areas of physics are welcome.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Projects}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Documented \MF{} Interface}
% In a future version, \FMF{} will have a more convenient and
% supported set of macros at the \MF{} level, including more general
% drawing primitives.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Less Formal Graphs}
% In addition to the well defined Feynman graphs of perturbation
% theory there are also less formal and more illustrative graphs in
% use. For example the ``quark diagrams'' familiar from papers on
% hadronic weak decays involve curved lines illustrating the formation
% of bound states, etc. Future versions of \FMF{} will provide better
% support for such graphs, without the need for raw \MF{} coding.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Virtual Graphs}
% \label{sec:virtual-pictures}
% In a future version, \FMF{} will be able to draw ``virtual''
% graphs, i.e.~graphs which are larger than the current limit enforced
% by numeric overflow at higher resolutions. This can be implemented
% by calculating the layout of a miniature graph and afterwards
% distributing the full graph among several \MF{} characters.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Conclusion}
% It goes without saying that \FMF{} is not perfect. There are
% cases where using a graphical drawing tool with a mouse will give
% more pleasing results in less time. But in most cases, \FMF{}
% will give satisfactory results without any fine tuning. These will
% be reproducible and independent from the computer it is running on.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Usage}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Invocation}
% Instructing \LaTeX{} to use \FMF{} is as simple as\footnote{As
% given, this applies to \LaTeX. But the installation file
% \texttt{feynmf209.ins} allows to generate special versions
% \texttt{feynmf209.sty} and \texttt{feynmp209.sty} which are
% compatible with the obsolete \LaTeX{} version 2.09. These files
% are to be used as documentstyle options.}
% \begin{verbatim}
% \usepackage{feynmf}
% \end{verbatim}
% and calling \MF{} should not be harder as
% \begin{verbatim}
% mf '\mode:=localmode; input foobar'
% \end{verbatim}
% where |foobar| is the name of your \MF{} output file and |localmode|
% is your local printer (e.g.~|laserjet|).
% The hard part usually lies in instructing \TeX{} and your favorite
% |dvi|-driver how to find the generated |tfm| and |gf| (resp.~|pk|)
% files. This is highly system dependent and can be trivial (as in
% the standard UNIX\footnote{UNIX was a trademark of UNIX Systems
% Laboratory, but is rumored to have been donored to X/Open.}
% \TeX{} installations) or almost impossible (as
% under MVS). Please consult your local guide or local ``\TeX{}
% Wizards'' on this point.
% If you have \MP, then you can use it by placing
% \begin{verbatim}
% \usepackage[dvips]{feynmp}
% \end{verbatim}
% in your \LaTeX{} source. Here |dvips| is an option for the
% \LaTeX{} |egraphics| package which is used for including the
% generated PostScript files. It should be replaced by your local
% supported |dvi| driver. Calling \MP{} is usually even simpler
% \begin{verbatim}
% mp foobar
% \end{verbatim}
% since there is no mode to be picked.
% Please keep in mind that \FMF{} has been developed for \LaTeXe{} and
% the \LaTeX~2.09 compatibility version will always be a retrofitted
% hack. I will accept bug reports for the 2.09 version, but I urge
% everybody to move to \LaTeX2e, which is the one and onloy supported
% \LaTeX{} right now.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \begin{figure}
% \begin{center}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \setlength{\unitlength}{0.012500in}%
% \begingroup\makeatletter\ifx\SetFigFont\undefined
% \def\x#1#2#3#4#5#6#7\relax{\def\x{#1#2#3#4#5#6}}%
% \expandafter\x\fmtname xxxxxx\relax \def\y{splain}%
% \ifx\x\y % LaTeX or SliTeX?
% \gdef\SetFigFont#1#2#3{%
% \ifnum #1<17\tiny\else \ifnum #1<20\small\else
% \ifnum #1<24\normalsize\else \ifnum #1<29\large\else
% \ifnum #1<34\Large\else \ifnum #1<41\LARGE\else
% \huge\fi\fi\fi\fi\fi\fi
% \csname #3\endcsname}%
% \else
% \gdef\SetFigFont#1#2#3{\begingroup
% \count@#1\relax \ifnum 25<\count@\count@25\fi
% \def\x{\endgroup\@setsize\SetFigFont{#2pt}}%
% \expandafter\x
% \csname \romannumeral\the\count@ pt\expandafter\endcsname
% \csname @\romannumeral\the\count@ pt\endcsname
% \csname #3\endcsname}%
% \fi
% \fi\endgroup
% \begin{picture}(377,400)(3,420)
% \thinlines
% \put( 40,740){\framebox(80,80){}}
% \put( 55,795){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}foo.tex}}}
% \put(280,760){\framebox(60,40){}}
% \put(295,780){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.mf}}}
% \put(160,680){\framebox(60,40){}}
% \put(170,705){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.log}}}
% \put(320,640){\framebox(60,40){}}
% \put(323,664){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.300gf}}}
% \put(100,600){\framebox(60,40){}}
% \put(110,620){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.t1}}}
% \put(180,600){\framebox(60,40){}}
% \put(185,622){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.t2}}}
% \put(260,560){\framebox(60,40){}}
% \put(270,585){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.tfm}}}
% \put( 40,420){\framebox(80,80){}}
% \put( 50,485){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}foo.dvi}}}
% \put(290,463){\oval(130,74)}
% \put(260,470){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}lpr}}}
% \thicklines
% \put(295,760){\vector(-3,-1){106.500}}
% \put(325,760){\vector( 1,-3){ 26.500}}
% \put(310,760){\vector(-1,-4){ 39.118}}
% \multiput(120,780)(11.85185,0.00000){14}{\line( 1, 0){ 5.926}}
% \put(280,780){\vector( 1, 0){0}}
% \put( 60,500){\vector( 0,-1){0}}
% \multiput( 60,740)(0.00000,-4.52830){53}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}}
% \put( 80,500){\vector(-1,-2){0}}
% \multiput(130,600)(-2.00000,-4.00000){25}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}}
% \put(120,480){\vector(-2,-1){0}}
% \multiput(280,560)(-4.00000,-2.00000){40}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}}
% \put(210,640){\vector( 1,-4){0}}
% \multiput(200,680)(1.11764,-4.47058){9}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}}
% \put(129,642){\vector(-4,-3){0}}
% \multiput(180,680)(-3.65714,-2.74286){14}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}}
% \thinlines
% \put(120,460){\vector( 1, 0){105}}
% \put(300,560){\vector( 0,-1){ 60}}
% \put(350,640){\vector( 0,-1){145}}
% \thicklines
% \put(105,494){\vector(-1,-1){0}}
% \multiput(211,600)(-3.19697,-3.19697){33}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}}
% \put(160,790){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}\LaTeX{} \#1}}}
% \put(360,535){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}dvi2xxx}}}
% \put(350,725){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}\MF}}}
% \put( 3,663){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}\LaTeX{} \#2}}}
% \end{picture}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \end{center}
% \caption{Flow of information in a \FMF{} application: The
% first \LaTeX{} pass is shown with a dashed line. The \MF{}
% pass is shown with the full lines and the second \LaTeX{} pass
% with dotted lines. The final dvi translation step is shown with
% thin lines.}
% \label{fig:flow}
% \end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The flow of information depicted in figure~\ref{fig:flow} looks much
% more complicated than it is. The important feature is that there a
% two sets of files which can be used to distribute a document:
% \begin{enumerate}
% \item{} Iff the recipient has a working \MF{} installation
% (which shouldn't be a problem, except for some impoverished
% commercial implementations), the document can be typset from the
% \LaTeX{} source \emph{alone}, by running \LaTeX{}, \MF{}
% and \LaTeX{} again (the latter step might have to be repeated to
% get cross references right).
% \item{} Another possibility (which doesn't require \MF{} on
% the recipient's side), is to distribute the \LaTeX{} source, the
% |tfm| and |gf| files (or |pk| files respectively) along with the
% label files with extension |t|$n$ (where $n$ as an integer).
% Distributing the \MF{} |log| files is a possible alternative
% for the latter, but discouraged, because these are prone to be
% erased accidentally.
% \end{enumerate}
% I should add one caveat here: some |dvi| file previewers
% (e.g.~xdvi(1) under UNIX) do \emph{not} reread font information if
% the |tfm| or |pk| files have changed, even though they reread the
% |dvi| file if it has changed. Thus you have to restart such
% previewers if you have made changes in diagrams to see these changes
% on the screen.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \begin{figure}
% \begin{center}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \setlength{\unitlength}{0.012500in}%
% \begingroup\makeatletter\ifx\SetFigFont\undefined
% \def\x#1#2#3#4#5#6#7\relax{\def\x{#1#2#3#4#5#6}}%
% \expandafter\x\fmtname xxxxxx\relax \def\y{splain}%
% \ifx\x\y % LaTeX or SliTeX?
% \gdef\SetFigFont#1#2#3{%
% \ifnum #1<17\tiny\else \ifnum #1<20\small\else
% \ifnum #1<24\normalsize\else \ifnum #1<29\large\else
% \ifnum #1<34\Large\else \ifnum #1<41\LARGE\else
% \huge\fi\fi\fi\fi\fi\fi
% \csname #3\endcsname}%
% \else
% \gdef\SetFigFont#1#2#3{\begingroup
% \count@#1\relax \ifnum 25<\count@\count@25\fi
% \def\x{\endgroup\@setsize\SetFigFont{#2pt}}%
% \expandafter\x
% \csname \romannumeral\the\count@ pt\expandafter\endcsname
% \csname @\romannumeral\the\count@ pt\endcsname
% \csname #3\endcsname}%
% \fi
% \fi\endgroup
% \begin{picture}(357,400)(3,420)
% \thinlines
% \put( 40,740){\framebox(80,80){}}
% \put( 55,795){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}foo.tex}}}
% \put( 40,420){\framebox(80,80){}}
% \put( 50,485){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}foo.dvi}}}
% \put(290,463){\oval(130,74)}
% \put(260,470){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}lpr}}}
% \put(100,640){\framebox(60,40){}}
% \put(110,660){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.t1}}}
% \put(180,640){\framebox(60,40){}}
% \put(185,662){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.t2}}}
% \put(220,580){\framebox(60,40){}}
% \put(230,605){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.1}}}
% \put(300,580){\framebox(60,40){}}
% \put(303,604){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.2}}}
% \put(280,760){\framebox(60,40){}}
% \put(295,780){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{tt}fd.mp}}}
% \thicklines
% \put(325,760){\vector( 0,-1){140}}
% \put(310,760){\vector(-1,-2){ 69}}
% \multiput(120,780)(11.85185,0.00000){14}{\line( 1, 0){ 5.926}}
% \put(280,780){\vector( 1, 0){0}}
% \put( 60,500){\vector( 0,-1){0}}
% \multiput( 60,740)(0.00000,-4.52830){53}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}}
% \put( 83,499){\vector(-1,-3){0}}
% \multiput(130,640)(-1.42424,-4.27273){33}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}}
% \put(115,486){\vector(-4,-3){0}}
% \multiput(240,580)(-3.56571,-2.67429){35}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}}
% \thinlines
% \put(120,460){\vector( 1, 0){105}}
% \put(260,580){\vector( 1,-2){ 40}}
% \thicklines
% \put(104,497){\vector(-3,-4){0}}
% \multiput(211,640)(-2.67900,-3.57200){40}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}}
% \thinlines
% \put(345,580){\vector(-1,-2){ 40}}
% \thicklines
% \put(295,760){\vector(-1,-1){ 82}}
% \put(295,760){\vector(-2,-1){164}}
% \put(120,480){\vector(-2,-1){0}}
% \multiput(320,580)(-4.00000,-2.00000){50}{\makebox(0.4444,0.6667){\SetFigFont{10}{12}{rm}.}}
% \put(160,790){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}\LaTeX \#1}}}
% \put( 3,663){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}\LaTeX \#2}}}
% \put(345,520){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}dvips}}}
% \put(340,685){\makebox(0,0)[lb]{\smash{\SetFigFont{12}{14.4}{rm}\MP}}}
% \end{picture}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \end{center}
% \caption{Flow of information in a \FMF{} application if \MP{} is
% used instead of \MF.}
% \label{fig:flowp}
% \end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Basic usage}
% The basic features of \FMF{} are (or rather ``should be'')
% available through the \LaTeX{} interface. Not knowledge of
% \MF{} is necessary.
% \DescribeEnv{fmffile}
% Upto 255 characters can be placed into one \MF{} file, they are
% enclosed in a single |fmffile| environment. The environment
% takes the filename as argument. Currently \FMF{} does \emph{not}
% check that the 255 character limit per file is not overrun.
% \begin{verbatim}
% \begin{fmffile}{foobar}
% ...
% \end{fmffile}
% \end{verbatim}
% Note that the filename for the \MF{} file given in the argument of
% the |fmffile| environment \emph{must not} be identical to the
% \LaTeX{} source file name, because the \MF{} |.log| would be
% overwritten and \LaTeX{} can no longer access the information in
% this |.log| file.
% \DescribeEnv{fmfchar}
% Draw one character and place it here. Arguments are
% |(|\meta{width}|,|\meta{height}|)| as in:
% \begin{verbatim}
% \begin{fmfchar}(40,25)
% ...
% \end{fmfchar}
% \end{verbatim}
% This environment does \emph{not} support labels, use |fmfchar*| if
% your diagrams contains labels.
% \DescribeEnv{fmfchar*}
% Same as |fmfchar|, but enclosed in a |picture| environment of the
% same size and supporting \LaTeX{} labels.
% \begin{verbatim}
% \begin{fmfchar*}(40,25)
% ...
% \end{fmfchar*}
% \end{verbatim}
% \DescribeMacro{\fmfleft}
% \DescribeMacro{\fmfright}
% \DescribeMacro{\fmfbottom}
% \DescribeMacro{\fmftop}
% \DescribeMacro{\fmfsurround}
% Positioning of
% external vertices has to done explicitely. The technical reason is
% that they would otherwise collapse with their neighbors, but
% practical reasons also suggest to give the user full control here.
% |\fmfleft{|\meta{v1}$[$|,|\ldots$]$|}| places the
% vertices in the comma separated list \meta{v1},\ldots
% equidistantly on a smooth path on the left side of the diagram.
% |\fmfright{|\meta{v1}$[$|,|\ldots$]$|}| does the same
% thing on the right. Similarly |\fmfbottom| and |\fmftop|, while
% |\fmfsurround{|\meta{v1}$[$|,|\ldots$]$|}|
% places its arguments on smooth path
% surrounding the diagram:
% \def\gallerylabels{%
% \fmfdotn{v}{4}%
% \fmflabel{$v_1$}{v1}%
% \fmflabel{$v_2$}{v2}%
% \fmflabel{$v_3$}{v3}%
% \fmflabel{$v_4$}{v4}}
% \begin{center}
% \label{p:galleries}
% \hfil\\
% \fbox{\begin{fmfchar*}(15,12)
% \fmfpen{thick}%
% \fmfbottomn{v}{4}\gallerylabels
% \fmfcmd{draw (bottom_gallery);}
% \end{fmfchar*}}\qquad
% \fbox{\begin{fmfchar*}(15,12)
% \fmfpen{thick}%
% \fmfleftn{v}{4}\gallerylabels
% \fmfcmd{draw (left_gallery);}
% \end{fmfchar*}}\qquad
% \fbox{\begin{fmfchar*}(15,12)
% \fmfpen{thick}%
% \fmfsurroundn{v}{7}\fmfdotn{v}{7}%
% \fmflabel{$v_1$}{v1}\fmflabel{$v_2$}{v2}%
% \fmflabel{$v_3$}{v3}\fmflabel{$v_4$}{v4}%
% \fmflabel{$v_5$}{v5}\fmflabel{$v_6$}{v6}%
% \fmflabel{$v_7$}{v7}%
% \fmfcmd{draw (surround_gallery);}
% \end{fmfchar*}}\qquad
% \fbox{\begin{fmfchar*}(15,12)
% \fmfpen{thick}%
% \fmftopn{v}{4}\gallerylabels
% \fmfcmd{draw (top_gallery);}
% \end{fmfchar*}}\qquad
% \fbox{\begin{fmfchar*}(15,12)
% \fmfpen{thick}%
% \fmfrightn{v}{4}\gallerylabels
% \fmfcmd{draw (right_gallery);}
% \end{fmfchar*}}\\
% \hfil
% \end{center}
% \DescribeMacro{\fmfpen}
% Pick up a pen of the specified size. |\fmfpen{|\meta{weight}|}|
% is used for changing the weight (i.e.~thickness) of the lines.
% Predefined sizes are |thin| and |thick|.
% \def\linesample#1{%
% \begin{fmfchar}(30,4)
% \fmfleft{i1,i2}
% \fmfright{o1,o2}
% \fmf{#1}{i1,o1}
% \end{fmfchar}}
% \begin{table}
% \begin{tabular}{lcll}
% Name & Example & Parameters & Aliases \\\hline
% |curly| & \linesample{curly} & |curly_len| & |gluon| \\
% |dbl_curly| & \linesample{dbl_curly} & |curly_len| & \\
% |dashes| & \linesample{dashes} & |dash_len| & \\
% |dashes_arrow| & \linesample{dashes_arrow} & |dash_len| & |scalar| \\
% |dbl_dashes| & \linesample{dbl_dashes} & |dash_len| & \\
% |dbl_dashes_arrow| & \linesample{dbl_dashes_arrow} & |dash_len| & \\
% |dots| & \linesample{dots} & |dot_len| & \\
% |dots_arrow| & \linesample{dots_arrow} & |dot_len| & |ghost| \\
% |dbl_dots| & \linesample{dbl_dots} & |dot_len| & \\
% |dbl_dots_arrow| & \linesample{dbl_dots_arrow} & |dot_len| & \\
% |phantom| & \linesample{phantom} & & \\
% |phantom_arrow| & \linesample{phantom_arrow} & & \\
% |plain| & \linesample{plain} & & |vanilla|\\
% |plain_arrow| & \linesample{plain_arrow} & & |fermion|,
% |electron|,
% |quark| \\
% |dbl_plain| & \linesample{dbl_plain} & & |double| \\
% |dbl_plain_arrow| & \linesample{dbl_plain_arrow} & & |double_arrow|,
% |heavy| \\
% |wiggly| & \linesample{wiggly} & |wiggly_len|& |boson|,
% |photon| \\
% |dbl_wiggly| & \linesample{dbl_wiggly} & |wiggly_len|&
% \end{tabular}
% \caption{Available line styles}
% \label{tab:line-styles}
% \end{table}
% \begin{table}
% \begin{tabular}{lp{60mm}}
% Name & Explanation \\\hline
% |tension| & draw a tighter ($>1$) or more loos ($<1$) arc \\
% |left| & draw on a halfcircle on the left \\
% |right| & draw on a halfcircle on the right \\
% |straight| & draw on a straight line \\
% |label| & \TeX{} text for labeling the arc \\
% |label.side| & force placement of the label on the |left| or
% |right| \\
% |label.dist| & place label at a distance |dist| \\
% |label.pos| & relative position of the label
% (not implemented yet!) \\
% |decoration.shape| & shape of decoration
% (not implemented yet!) \\
% |decoration.size| & size of decoration
% (not implemented yet!) \\
% |decoration.pos| & relative position of decoration
% (not implemented yet!) \\
% |decoration.filled| & fill, shade or hatch decoration
% (not implemented yet!) \\
% |decoration.angle| & rotate decoration relative to default
% (not implemented yet!)
% \end{tabular}
% \caption{Available line options}
% \label{tab:line-options}
% \end{table}
% \DescribeMacro{\fmf}
% This is the the most frequently used macro in \FMF{} applications.
% |\fmf{|\meta{style}\allowbreak
% $[$|,|\meta{opt}\allowbreak
% $[$|=|\meta{val}$]$|,|\ldots$]$|}{|\meta{v1}|,|\meta{v2}\allowbreak
% $[$|,|\ldots$]$|}|
% connects the vertices \textit{v1,v2,\ldots} with a line of style
% \meta{style}, using a set of options \meta{opt} with (optional)
% value \meta{val}. If a vertex is not
% known yet, it is added to the diagram. Note that the actual drawing
% is not done immediately, because the positions can only be
% calculated when \emph{all} vertices are known. The currently
% available styles are collected in table~\ref{tab:line-styles}. Most
% names should be self explanatory
% and are not discussed further.
% The |dashes|, |dots|, |phantom| and |plain| styles can optionally be
% decorated with an arrow as shown above. All styles, including
% |curly| and |wiggly|, can be doubled. But arrows are not available
% for the latter two, because esthetically pleasing results can not be
% expected. The |phantom|
% style is special, because it
% only enters the vertices and does \emph{not} cause a line to be
% drawn. This is extremely useful for advanced layout features, as
% explained below.
% The supported options are collected in
% table~\ref{tab:line-options}\footnote{%
% \begin{dubious}
% One particulary useful further option would be \texttt{smooth},
% allowing for several lines joined smoothly. Early
% experimentation has shown however, that the results are not
% always what one expects and that there is a lot of room for
% abuse.
% \end{dubious}}.
% Note that each of the dot separated components of the options can be
% abbreviated. For example, |l.d| is equivalent to |label.dist|. The
% result of ambiguous matches is however undefined.
% \begin{table}
% \begin{tabular}{lp{60mm}}
% Name & Explanation \\\hline
% |label| & \TeX{} text for labeling the vertex \\
% |label.angle| & force placement of the label at the given
% angle from the vertex \\
% |label.dist| & place label at a distance |dist| \\
% |decoration.shape| & shape of decoration \\
% |decoration.size| & size of decoration \\
% |decoration.filled| & fill, shade or hatch decoration \\
% |decoration.angle| & rotate decoration
% \end{tabular}
% \caption{Available vertex options}
% \label{tab:vertex-options}
% \end{table}
% \DescribeMacro{\fmfv}
% Declare vertices with options:
% |\fmfv{|\meta{shape}$[$|=|\meta{val}$]$\allowbreak
% $[$|,|\meta{opt}\allowbreak
% $[$|=|\meta{val}$]$|,|\ldots$]$|}{|\meta{v1}\allowbreak
% $[$|,|\ldots$]$|}|
% This is used for adding labels to a vertex and for specifying other
% decoration. Supported options are collected in
% table~\ref{tab:vertex-options}. Here the same abbreviation
% mechanism as above is in effect. The available |shape|s are listed
% in various filling styles in table~\ref{tab:vertex-shapes}\footnote{%
% If the variable \texttt{feymfwizard} is \texttt{true} (e.g.~after
% calling the \texttt{fmfwizard} macro),
% it is also possible to specify any \MF{} expression that evaluates
% to a \texttt{path}. Naturally, this has to used with great care,
% because strange errors can be triggered by typos!}.
% \def\VertexSample#1#2{%
% \begin{fmfchar}(8,8)
% \fmfforce{(.5w,.4h)}{c}
% \fmfv{d.shape=#1,d.filled=#2}{c}
% \end{fmfchar}}
% \def\VertexSamples#1{%
% \VertexSample{#1}{-.5} & \VertexSample{#1}{0}
% & \VertexSample{#1}{.5} & \VertexSample{#1}{1}}
% \begin{table}
% \begin{center}
% \begin{tabular}{lcccc}
% & |filled=-.5| & |filled=0| & |filled=.5| & |filled=1| \\
% \hline
% |circle| & \VertexSamples{circle} \\
% |square| & \VertexSamples{square} \\
% |triangle| & \VertexSamples{triangle} \\
% |diamond| & \VertexSamples{diamond} \\
% |pentagon| & \VertexSamples{pentagon} \\
% |hexagon| & \VertexSamples{hexagon} \\
% |triagram| & \VertexSamples{triagram} \\
% |tetragram|& \VertexSamples{tetragram} \\
% |pentagram|& \VertexSamples{pentagram} \\
% |hexagram| & \VertexSamples{hexagram}
% \end{tabular}
% \end{center}
% \caption{Available vertex shapes and fill styles.}
% \label{tab:vertex-shapes}
% \end{table}
% \DescribeMacro{\fmfblob}
% Draw a blob of the specified diameter at the vertices.
% |\fmfblob{|\meta{diameter}|}{|\meta{v1}\allowbreak
% $[$|,|\ldots$]$|}| is equivalent to
% |\fmfv{decor.shape=circle,|\allowbreak|decor.filled=.5,|\allowbreak
% |decor.size=|\meta{diameter}\allowbreak
% |}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
% \DescribeMacro{\fmfdot}
% Draw a dot at the vertices given as arguments.
% |\fmfdot{|\meta{v1}\allowbreak
% $[$|,|\ldots$]$|}| is equivalent to
% |\fmfv{decor.shape=circle,|\allowbreak|decor.filled=1,|\allowbreak
% |decor.size=2thick|\allowbreak
% |}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
% \DescribeMacro{\fmfposition}
% Calculate the positions of the vertices based on the arcs which are
% defined up to this point. Usually this calculation is performed
% automatically at the end of the |fmfchar| environment. Calling it
% explicitely, is useful for adding arcs which should not enter the
% calculation.
% \DescribeMacro{\fmfforce}
% |\fmfforce{|\meta{pos}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
% forces the position \meta{pos} of the vertices \meta{v1}\ldots,
% bypassing the automatic layout.
% \DescribeMacro{\fmfshift}
% |\fmfforce{|\meta{dist}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
% shifts the position of the vertices \meta{v1}\ldots{} by \meta{dist}
% from the automatic layout.
% \DescribeMacro{\fmffixed}
% |\fmfforce{|\meta{dist}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
% fixes the distance between subsequent vertices in the list
% \meta{v1}\ldots{} to \meta{dist}.
% This command should be used with care, because it is possible to
% overconstrain the layout of the graph and the error messages will be
% obscure to a novice user.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Examples}
% As an example, consider drawing a straightforward box diagram,
% familier from $K$-$\bar K$, $D$-$\bar D$, and $B$-$\bar B$ mixing.
% The commands for the labels are not shown here, they are discussed
% in section~\ref{sec:labels}
% \vspace*{\baselineskip}
% \begin{minipage}{0.6\linewidth}
% We start the diagram and pick up a thick pen:
% \begin{verbatim}
% \begin{fmfchar}(40,25)
% \fmfpen{thick}
% \end{verbatim}
% The incoming and outcoming vertices are placed on the left and
% right hand side, respectively:
% \begin{verbatim}
% \fmfleft{i1,i2}
% \fmfright{o1,o2}
% \end{verbatim}
% Now we tell \FMF{} how the arcs are connected.
% \begin{verbatim}
% \fmf{fermion}{i1,v1,v3,o1}
% \fmf{fermion}{o2,v4,v2,i2}
% \fmf{photon}{v1,v2}
% \fmf{photon}{v3,v4}
% \end{verbatim}
% Finally we tell \FMF{} to draw dots at the vertices and we're
% done.
% \begin{verbatim}
% \fmfdot{v1,v2,v3,v4}
% \end{fmfchar}
% \end{verbatim}
% \end{minipage}
% \hfill
% \begin{minipage}{0.35\linewidth}
% \begin{center}
% \begin{fmfchar*}(40,25)
% \fmfpen{thick}
% \fmfleft{i1,i2}
% \fmflabel{$\noexpand\bar b$}{i1}
% \fmflabel{$d$}{i2}
% \fmfright{o1,o2}
% \fmflabel{$\noexpand\bar d$}{o1}
% \fmflabel{$b$}{o2}
% \fmf{fermion}{i1,v1}
% \fmf{fermion,label=$\noexpand\bar t,,\noexpand\bar c,,
% \noexpand\bar u$,l.side=right}{v1,v3}
% \fmf{fermion}{v3,o1}
% \fmf{fermion}{o2,v4}
% \fmf{fermion,label=$t,,c,,u$,l.side=right}{v4,v2}
% \fmf{fermion}{v2,i2}
% \fmf{photon,label=$W^+$,l.side=left}{v1,v2}
% \fmf{photon,label=$W^-$,l.side=right}{v3,v4}
% \fmfdot{v1,v2,v3,v4}
% \end{fmfchar*}
% \end{center}
% \end{minipage}
% \label{page:simple-examples}
% Here is the resonant $s$-channel contribution to $e^+e^-\to 4f$.
% (From now on, we do no longer display the
% |\begin{fmfchar}(40,25)|, |\fmfpen{thick}|, \ldots,
% |\end{fmfchar}| surrounding all pictures.)
% \vspace*{\baselineskip}
% \begin{minipage}{0.6\linewidth}
% \begin{verbatim}
% \fmfleft{i1,i2}
% \fmfright{o1,o2,o3,o4}
% \fmf{fermion}{i1,v1,i2}
% \fmf{photon}{v1,v2}
% \fmfblob{.15w}{v2}
% \fmf{photon}{v2,v3}
% \fmf{fermion}{o1,v3,o2}
% \fmf{photon}{v2,v4}
% \fmf{fermion}{o4,v4,o3}
% \end{verbatim}
% \end{minipage}
% \hfill
% \begin{minipage}{0.38\linewidth}
% \begin{center}
% \fmfframe(0,5)(5,7){%
% \begin{fmfchar*}(40,25)
% \fmfpen{thick}
% \fmfleft{i1,i2}
% \fmfright{o1,o2,o3,o4}
% \fmflabel{$e_-$}{i1}
% \fmflabel{$e_+$}{i2}
% \fmf{fermion}{i1,v1,i2}
% \fmf{photon}{v1,v2}
% \fmfblob{.15w}{v2}
% \fmf{photon}{v2,v3}
% \fmflabel{$\noexpand\mu_+$}{o1}
% \fmflabel{$\noexpand\nu_{\noexpand\mu}$}{o2}
% \fmf{fermion}{o1,v3,o2}
% \fmf{photon}{v2,v4}
% \fmflabel{$\noexpand\bar c$}{o4}
% \fmflabel{$s$}{o3}
% \fmf{fermion}{o4,v4,o3}
% \end{fmfchar*}}
% \end{center}
% \end{minipage}
% And the resonant $t$-channel contribution:
% \vspace*{\baselineskip}
% \begin{minipage}{0.6\linewidth}
% \begin{verbatim}
% \fmfleft{i1,i2}
% \fmfright{o1,o2,o3,o4}
% \fmf{fermion}{i1,v1,v2,i2}
% \fmf{photon}{v1,v3}
% \fmf{fermion}{o1,v3,o2}
% \fmf{photon}{v2,v4}
% \fmf{fermion}{o4,v4,o3}
% \end{verbatim}
% \end{minipage}
% \hfill
% \begin{minipage}{0.38\linewidth}
% \begin{center}
% \fmfframe(0,5)(5,7){%
% \begin{fmfchar*}(40,25)
% \fmfpen{thick}
% \fmfleft{i1,i2}
% \fmfright{o1,o2,o3,o4}
% \fmflabel{$e_-$}{i1}
% \fmflabel{$e_+$}{i2}
% \fmf{fermion}{i1,v1,v2,i2}
% \fmf{photon}{v1,v3}
% \fmflabel{$\noexpand\mu_+$}{o1}
% \fmflabel{$\noexpand\nu_{\noexpand\mu}$}{o2}
% \fmf{fermion}{o1,v3,o2}
% \fmf{photon}{v2,v4}
% \fmflabel{$\noexpand\bar c$}{o4}
% \fmflabel{$s$}{o3}
% \fmf{fermion}{o4,v4,o3}
% \end{fmfchar*}}
% \end{center}
% \end{minipage}
% Actually, these three diagrams can be improved slightly by using
% |phantom| arcs, which will be discussed in the next section.
% Two point loop diagrams pose another set of problems. We
% must have a way of specifying that one or more of the lines
% connecting the two vertices are \emph{not} connected by a straight
% line. The options |left|, |right| and |straight| offer the
% possibility to connect two vertices by a semicircle detour, either
% on the left or on the right. Since by default all lines contribute
% to the tension between two vertices, the |tension| option allows us
% to reduce this tension. The next examples shows both options in
% action. The lower fermion line is given an tension of~$1/3$ to
% make is symmetrical with the upper line with consists of three parts.
% The loop photon is using a detour on the right and does not
% contribute any tension.
% \vspace*{\baselineskip}
% \begin{minipage}{0.6\linewidth}
% \begin{verbatim}
% \fmfleft{i1,i2}
% \fmfright{o1}
% \fmf{fermion,tension=1/3}{i1,v1}
% \fmf{plain}{v1,v2}
% \fmf{fermion}{v2,v3}
% \fmf{photon,right,tension=0}{v2,v3}
% \fmf{plain}{v3,i2}
% \fmf{photon}{v1,o1}
% \end{verbatim}
% \end{minipage}
% \hfill
% \begin{minipage}{0.35\linewidth}
% \begin{center}
% \begin{fmfchar*}(40,25)
% \fmfpen{thick}
% \fmfleft{i1,i2}
% \fmflabel{$p^{\noexpand\prime}$}{i1}
% \fmflabel{$p$}{i2}
% \fmfright{o1}
% \fmflabel{$p+p^{\noexpand\prime}$}{o1}
% \fmf{fermion,tension=1/3}{i1,v1}
% \fmf{plain}{v1,v2}
% \fmf{fermion,label=$p-k$,l.side=left}{v2,v3}
% \fmf{photon,right,tension=0,label=$k$}{v2,v3}
% \fmf{plain}{v3,i2}
% \fmf{photon}{v1,o1}
% \end{fmfchar*}
% \end{center}
% \end{minipage}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Labels}
% \label{sec:labels}
% Let us now come back to the examples on
% page~\pageref{page:simple-examples} and discuss how to add the
% labels.
% \DescribeMacro{\fmflabel}
% The macro |\fmflabel{|\meta{label}|}{|\meta{v}|}| adds the label
% \meta{label} to the vertex \meta{v}. In the current implementation,
% there can be only a single label for each vertex. Thus earlier
% calls to |\fmflabel| for the same vertex will be overwritten.
% \meta{label} will be placed with the |\put| command of the \LaTeX{}
% |picture| environment. \emph{It is absolutely necessary to quote
% \emph{each} \TeX{} control sequence appearing in \meta{label} with}
% |\noexpand|. \emph{Otherwise all kinds of disasters are bound to
% happen, causing at the very least some obscure error messages!}
% Note that the |fmfchar*| environment must be used to use labels,
% they will silently disappear in |fmfchar|.
% |\fmflabel| gives the user \emph{no} control on the placement of
% the the label (see below for a more fine-grained control provided by
% the options to the |\fmfv| macro). The label is placed using the
% following algorithm:
% \begin{enumerate}
% \item{} The reference point of the box containing \meta{label} is
% placed at the distance |3thick| on the continuation of the
% straight line connecting the center of the picture with the
% vertex \meta{v}.
% \item{} The reference point of the box is chosen such that the
% contents of the box is on the outside of the vertex (with
% respect to the center of the diagram). It is chosen from the
% four corners and the four midpoints of the sides.
% \end{enumerate}
% Therefore the four external particles in the~$B$-$\bar B$ mixing
% diagram on page~\pageref{page:simple-examples} are labelled simply
% by:
% \begin{verbatim}
% \fmflabel{$\noexpand\bar b$}{i1}
% \fmflabel{$d$}{i2}
% \fmflabel{$\noexpand\bar d$}{o1}
% \fmflabel{$b$}{o2}
% \end{verbatim}
% \begin{dubious}
% Explain more of the |label| option and the default placement rules.
% \end{dubious}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Advanced usage}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Shrinking}
% \DescribeEnv{fmfshrink}
% Shrink the lineswidths and similar parameters in the enclosed section.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Multiple vertices and arcs}
% \DescribeMacro{\fmfleftn}
% \DescribeMacro{\fmfrightn}
% \DescribeMacro{\fmfbottomn}
% \DescribeMacro{\fmftopn}
% \DescribeMacro{\fmfsurroundn}
% The macro is|\fmfleftn| is similar to |\fmfleft|, but
% |\fmfleftn{|\meta{v}\allowbreak|}{|\meta{n}|}| places the
% vertices
% \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}. Analogously for
% the macros |\fmfrightn|, |\fmfbottomn|, |\fmftopn| and
% |\fmfsurroundn|.
% \DescribeMacro{\fmfvn}
% The macro |\fmfvn| is similar to |\fmfv|, but
% |\fmfvn{|\meta{vertex}\allowbreak|}{|\meta{v}\allowbreak|}{|\meta{n}|}|
% places the vertices \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}.
% \DescribeMacro{\fmfdotn}
% \DescribeMacro{\fmfblobn}
% The macros |\fmfdotn| and |\fmfblobn| are similar to the |\fmfdot|
% and |\fmfblob|, but |\fmfdotn{|\meta{v}|}{|\meta{n}|}| places the
% vertices \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}. Analogously for
% |\fmfblobn|.
% \DescribeEnv{fmffor}
% The environment |\begin{fmffor}{|\meta{var}\allowbreak
% |}{|\meta{from}\allowbreak|}{|\meta{step}\allowbreak
% |}{|\meta{to}\allowbreak|}|\allowbreak\meta{body}\allowbreak
% |\end{fmffor}|
% executes \meta{body} multiple times, setting \meta{var} to
% $\meta{from}, \meta{from}+\meta{step}, \ldots, \meta{to}$.
% \DescribeMacro{\fmfcyclen}
% \DescribeMacro{\fmfrcyclen}
% The macro |\fmfcyclen{|\meta{style}|}{|\meta{v}|}{|\meta{n}|}|
% cyclically connects the vertices
% \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}. |\fmfcyclen| operates in
% reverse order.
% An advanced application of the above \FMF{} features is shown in
% figure~\ref{fig:euler-heisenberg}, which is generated by calling
% the \TeX{} macro
% \begin{verbatim}
% \def\EulerHeisenberg#1{%
% \begin{fmfchar}(40,25)
% \fmfpen{thick}
% \fmfsurroundn{e}{#1}
% \begin{fmffor}{n}{1}{1}{#1}
% \fmf{photon}{e[n],i[n]}
% \end{fmffor}
% \fmfcyclen{fermion,tension=#1/8}{i}{#1}
% \end{fmfchar}}
% \end{verbatim}
% with the arguments 4, 6, 8, and 10, respectively.
% \def\EulerHeisenberg#1{%
% \begin{fmfchar}(40,25)
% \fmfpen{thick}
% \fmfsurroundn{e}{#1}
% \begin{fmffor}{n}{1}{1}{#1}
% \fmf{photon}{e[n],i[n]}
% \end{fmffor}
% \fmfcyclen{fermion,tension=#1/8}{i}{#1}
% \end{fmfchar}}
% \begin{figure}
% \begin{center}
% \EulerHeisenberg{4} \qquad \EulerHeisenberg{6}
% \end{center}
% \begin{center}
% \EulerHeisenberg{8} \qquad \EulerHeisenberg{10}
% \end{center}
% \caption{Higher order terms in the Euler-Heisenberg lagrangian.}
% \label{fig:euler-heisenberg}
% \end{figure}
% Similarly, we can draw the diagrams in figures~\ref{fig:PP-rings}
% and~\ref{fig:PP-rings} from many particle physics:
% \begin{verbatim}
% \def\PPRing#1{%
% \begin{fmfchar}(20,20)
% \fmfsurroundn{v}{#1}
% \fmfdotn{v}{#1}
% \fmfcyclen{fermion,right=0.25}{v}{#1}
% \fmfcyclen{fermion,left=0.25}{v}{#1}
% \end{fmfchar}}
% \def\PHRing#1{%
% \begin{fmfchar}(20,20)
% \fmfsurroundn{v}{#1}
% \fmfdotn{v}{#1}
% \fmfcyclen{fermion,right=0.25}{v}{#1}
% \fmfrcyclen{fermion,right=0.25}{v}{#1}
% \end{fmfchar}}
% \end{verbatim}
% \def\PPRing#1{%
% \begin{fmfchar}(20,20)
% \fmfsurroundn{v}{#1}
% \fmfdotn{v}{#1}
% \fmfcyclen{fermion,right=0.25}{v}{#1}
% \fmfcyclen{fermion,left=0.25}{v}{#1}
% \end{fmfchar}}
% \def\PHRing#1{%
% \begin{fmfchar}(20,20)
% \fmfsurroundn{v}{#1}
% \fmfdotn{v}{#1}
% \fmfcyclen{fermion,right=0.25}{v}{#1}
% \fmfrcyclen{fermion,right=0.25}{v}{#1}
% \end{fmfchar}}
% \begin{figure}
% \begin{center}
% \PPRing{3}\qquad\PPRing{4}\qquad\PPRing{5}\qquad\PPRing{6}
% \end{center}
% \caption{Particle-particle ring diagrams}
% \label{fig:PP-rings}
% \end{figure}
% \begin{figure}
% \begin{center}
% \PHRing{3}\qquad\PHRing{4}\qquad\PHRing{5}\qquad\PHRing{6}
% \end{center}
% \caption{Particle-hole ring diagrams}
% \label{fig:PH-rings}
% \end{figure}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Tight arcs}
% If you add to any arc one or more |phantom| arcs they will cause
% a tighter bonding between the vertices involved
% \begin{verbatim}
% \fmf{fermion}{v1,v2}
% \fmf{phantom}{v1,v2}
% \end{verbatim}
% which is equivalent to
% \begin{verbatim}
% \fmf{fermion,tension=2}{v1,v2}
% \end{verbatim}
% The |phantom| arc has to be added \emph{before} any |\fmfposition|
% involving these vertices, of course. Here is an example from deep
% inelastic scattering. (We do not show the |\fmfcmd{}|s in this
% example which are used for decorating the incoming proton and do not
% affect \FMF's layout decisions.)
% \vspace*{\baselineskip}
% \begin{minipage}{0.6\linewidth}
% \begin{verbatim}
% \fmfleft{ip,il}
% \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
% \fmf{fermion}{ip,vp,vq,oq3}
% \fmf{fermion}{vp,oq1}
% \fmf{fermion}{vp,oq2}
% \fmf{photon}{vl,vq}
% \fmf{fermion}{il,vl,ol}
% \fmfblob{.15w}{vp}
% \fmfdot{vq}
% \end{verbatim}
% \end{minipage}
% \hfill
% \begin{minipage}{0.35\linewidth}
% \begin{center}
% \begin{fmfchar}(40,25)
% \fmfpen{thick}
% \fmfleft{ip,il}
% \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
% \fmf{fermion}{ip,vp,vq,oq3}
% \fmf{fermion}{vp,oq1}
% \fmf{fermion}{vp,oq2}
% \fmf{photon}{vl,vq}
% \fmf{fermion}{il,vl,ol}
% \fmfposition
% \fmfforce{vloc ip+(0,2thick)}{ipp}
% \fmfforce{vloc ip-(0,2thick)}{ipm}
% \fmfforce{vloc vp+(0,2thick)}{vpp}
% \fmfforce{vloc vp-(0,2thick)}{vpm}
% \fmfshift{0.12 (vloc ip - vloc vp)}{vpp}
% \fmfshift{0.10 (vloc ip - vloc vp)}{vpm}
% \fmf{plain}{ipp,vpp}
% \fmf{plain}{ipm,vpm}
% \fmfblob{.15w}{vp}
% \fmfdot{vq}
% \end{fmfchar}
% \end{center}
% \end{minipage}
% As it stands, all vertices come out too far to the right, because
% the greater number of outgoing lines pulls them over. Adding
% |\fmf{phantom}| makes the bond between the incoming vertices and the
% interactions tighter and produces a better balanced picture:
% \vspace*{\baselineskip}
% \begin{minipage}{0.6\linewidth}
% \begin{verbatim}
% \fmfleft{ip,il}
% \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
% \fmf{fermion}{ip,vp,vq,oq3}
% \fmf{phantom}{ip,vp}
% \fmf{fermion}{vp,oq1}
% \fmf{fermion}{vp,oq2}
% \fmf{photon}{vl,vq}
% \fmf{fermion}{il,vl,ol}
% \fmf{phantom}{il,vl}
% \fmfblob{.15w}{vp}
% \fmfdot{vq}
% \end{verbatim}
% \end{minipage}
% \hfill
% \begin{minipage}{0.35\linewidth}
% \begin{center}
% \begin{fmfchar}(40,25)
% \fmfpen{thick}
% \fmfleft{ip,il}
% \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
% \fmf{fermion}{ip,vp,vq,oq3}
% \fmf{phantom}{ip,vp}
% \fmf{fermion}{vp,oq1}
% \fmf{fermion}{vp,oq2}
% \fmf{photon}{vl,vq}
% \fmf{fermion}{il,vl,ol}
% \fmf{phantom}{il,vl}
% \fmfposition
% \fmfforce{vloc ip+(0,2thick)}{ipp}
% \fmfforce{vloc ip-(0,2thick)}{ipm}
% \fmfforce{vloc vp+(0,2thick)}{vpp}
% \fmfforce{vloc vp-(0,2thick)}{vpm}
% \fmfshift{0.16 (vloc ip - vloc vp)}{vpp}
% \fmfshift{0.14 (vloc ip - vloc vp)}{vpm}
% \fmf{plain}{ipp,vpp}
% \fmf{plain}{ipm,vpm}
% \fmfblob{.15w}{vp}
% \fmfdot{vq}
% \end{fmfchar}
% \end{center}
% \end{minipage}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Loose arcs}
% Adding arcs \emph{after} any |\fmfposition| involving these
% vertices will make these arcs loose, i.e.~they will not contribute
% to the bonding between the vertices.
% Consider the following example: suppose we want to draw a ladder
% diagram contributing to the quark form factor. Simply linking in
% the gluons does not produce a satisfactory result:
% \vspace*{\baselineskip}
% \begin{minipage}{0.6\linewidth}
% \begin{verbatim}
% \fmfleft{i1} \fmfright{o1,o2}
% \fmf{photon}{i1,v4}
% \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
% \fmf{gluon}{v1,v7}
% \fmf{gluon}{v2,v6}
% \fmf{gluon}{v3,v5}
% \end{verbatim}
% \end{minipage}
% \hfill
% \begin{minipage}{0.35\linewidth}
% \begin{center}
% \begin{fmfchar}(40,25)
% \fmfpen{thick}
% \fmfleft{i1} \fmfright{o1,o2}
% \fmf{photon}{v4,i1}
% \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
% \fmf{gluon}{v1,v7}
% \fmf{gluon}{v2,v6}
% \fmf{gluon}{v3,v5}
% \end{fmfchar}
% \end{center}
% \end{minipage}
% What went wrong? Obviously the gluons are bonding the quark lines
% too strongly. The fix is simple: just exclude the gluons from the
% calculation and add them later as infinitely stretchable:
% \vspace*{\baselineskip}
% \begin{minipage}{0.6\linewidth}
% \begin{verbatim}
% \fmfleft{i1} \fmfright{o1,o2}
% \fmf{photon}{i1,v4}
% \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
% \fmfposition
% \fmf{gluon}{v1,v7}
% \fmf{gluon}{v2,v6}
% \fmf{gluon}{v3,v5}
% \end{verbatim}
% \end{minipage}
% \hfill
% \begin{minipage}{0.35\linewidth}
% \begin{center}
% \begin{fmfchar}(40,25)
% \fmfpen{thick}
% \fmfleft{i1} \fmfright{o1,o2}
% \fmf{photon}{v4,i1}
% \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
% \fmfposition
% \fmf{gluon}{v1,v7}
% \fmf{gluon}{v2,v6}
% \fmf{gluon}{v3,v5}
% \end{fmfchar}
% \end{center}
% \end{minipage}
% Another instructive example is the following: imagine you want to
% draw a typical non-resonant contribution to~$e^+e^-\to 4f$. The
% obvious solution doesn's look right.
% \vspace*{\baselineskip}
% \begin{minipage}{0.6\linewidth}
% \begin{verbatim}
% \fmfleft{i1,i2}
% \fmfright{o1,o2,o3,o4}
% \fmf{fermion}{i1,v1,i2}
% \fmf{photon}{v1,v2}
% \fmf{fermion}{o1,v2,v3,o4}
% \fmf{photon}{v3,v4}
% \fmf{fermion}{o3,v4,o2}
% \end{verbatim}
% \end{minipage}
% \hfill
% \begin{minipage}{0.35\linewidth}
% \begin{center}
% \begin{fmfchar}(40,25)
% \fmfpen{thick}
% \fmfleft{i1,i2}
% \fmfright{o1,o2,o3,o4}
% \fmf{fermion}{i1,v1,i2}
% \fmf{photon}{v1,v2}
% \fmf{fermion}{o1,v2,v3,o4}
% \fmf{photon}{v3,v4}
% \fmf{fermion}{o3,v4,o2}
% \end{fmfchar}
% \end{center}
% \end{minipage}
% One way to fix it is to |\fmfshift| the three rightmost vertices by
% hand:
% \vspace*{\baselineskip}
% \begin{minipage}{0.6\linewidth}
% \begin{verbatim}
% \fmfleft{i1,i2}
% \fmfright{o1,o2,o3,o4}
% \fmf{fermion}{i1,v1,i2}
% \fmf{photon}{v1,v2}
% \fmf{fermion}{o1,v2,v3,o4}
% \fmf{photon}{v3,v4}
% \fmf{fermion}{o3,v4,o2}
% \fmfposition
% \fmfshift{-.1w,0}{v2,v3,v4}
% \end{verbatim}
% \end{minipage}
% \hfill
% \begin{minipage}{0.35\linewidth}
% \begin{center}
% \begin{fmfchar}(40,25)
% \fmfpen{thick}
% \fmfleft{i1,i2}
% \fmfright{o1,o2,o3,o4}
% \fmf{fermion}{i1,v1,i2}
% \fmf{photon}{v1,v2}
% \fmf{fermion}{o1,v2,v3,o4}
% \fmf{photon}{v3,v4}
% \fmf{fermion}{o3,v4,o2}
% \fmfposition
% \fmfshift{-.1w,0}{v2,v3,v4}
% \end{fmfchar}
% \end{center}
% \end{minipage}
% A smarter solution is again to make certain arcs stretchable:
% \vspace*{\baselineskip}
% \begin{minipage}{0.6\linewidth}
% \begin{verbatim}
% \fmfleft{i1,i2}
% \fmfright{o1,o2,o3,o4}
% \fmf{fermion}{i1,v1,i2}
% \fmf{photon}{v1,v2}
% \fmf{fermion}{o1,v2,v3,o4}
% \fmfposition
% \fmf{photon}{v3,v4}
% \fmf{fermion}{o3,v4,o2}
% \end{verbatim}
% \end{minipage}
% \hfill
% \begin{minipage}{0.35\linewidth}
% \begin{center}
% \begin{fmfchar}(40,25)
% \fmfpen{thick}
% \fmfleft{i1,i2}
% \fmfright{o1,o2,o3,o4}
% \fmf{fermion}{i1,v1,i2}
% \fmf{photon}{v1,v2}
% \fmf{fermion}{o1,v2,v3,o4}
% \fmfposition
% \fmf{photon}{v3,v4}
% \fmf{fermion}{o3,v4,o2}
% \end{fmfchar}
% \end{center}
% \end{minipage}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Avoiding continuously tight and loose arcs}
% I have been very reluctant to implement continuously tight and loose
% arcs in \FMF, because it introduces to much opportunity for
% ``fiddling'' on the user's part. However, since the present
% implementation blends rather nicely with the options syntax, I have
% decided to add it anyway. I hope that most diagrams will be created
% without too much ``fiddling''.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Raw \MF}
% Some more advanced features of \FMF{} are more conveniently
% accessed through raw \MF{} commands. This can either be
% achieved by preparing a \MF{} input file or by using |\fmfcmd|
% extensively. The latter apprach is usally more convenient.
% \DescribeMacro{\fmfcmd}
% The |\fmfcmd| macro writes its argument into the \MF{} input
% file generated by \FMF. While some experience in using
% \MF{} doesn't hurt here, this approach can simplify the
% production of complex diagrams considerably.
% Here's an interesting ``abuse'' of \FMF. Using the undocumented
% \MF{} macros (like |vdraw_vertex_label|) is possible, though not
% supported. In a future versions, these features will be made
% available through supported interfaces.
% \begin{minipage}{0.6\linewidth}
% \begin{verbatim}
% \begin{fmfchar*}(40,40)\fmfcmd{
% pair o,xm,xp,ym,yp;
% pair v.loc; string v.lbl;
% o:=(.5w,.1h);
% xm:=(0,.1h); xp:=(w,.1h);
% ym:=(.5w,0); yp:=(.5w,h);
% v.loc := xp; v.lbl := "$x$";
% v.lbl.ang := -135; v.lbl.dist := 2;
% vdraw_vertex_label v;
% v.loc := yp; v.lbl := "$y=x^2$";
% vdraw_vertex_label v;
% pickup pencircle scaled thin;
% draw xm--xp; draw ym--yp;
% pickup pencircle scaled thick;
% xs:=xpart(xp-o); ys:=ypart(yp-o);
% draw (o + (-xs,ys)) for n = -9 upto 10:
% --(o + (xs*(n/10),ys*((n/10)**2)))
% endfor;}
% \end{fmfchar*}
% \end{verbatim}
% \end{minipage}
% \hfill
% \begin{minipage}{0.35\linewidth}
% \begin{center}
% \begin{fmfchar*}(40,40)\fmfcmd{
% pair o,xm,xp,ym,yp;
% pair v.loc; string v.lbl;
% o:=(.5w,.1h);
% xm:=(0,.1h); xp:=(w,.1h);
% ym:=(.5w,0); yp:=(.5w,h);
% v.loc := xp; v.lbl := "$x$";
% v.lbl.ang := -135; v.lbl.dist := 2;
% vdraw_vertex_label v;
% v.loc := yp; v.lbl := "$y=x^2$";
% vdraw_vertex_label v;
% pickup pencircle scaled thin;
% draw xm--xp; draw ym--yp;
% pickup pencircle scaled thick;
% xs:=xpart(xp-o); ys:=ypart(yp-o);
% draw (o + (-xs,ys)) for n = -9 upto 10:
% --(o + (xs*(n/10),ys*((n/10)**2)))
% endfor;}
% \end{fmfchar*}
% \end{center}
% \end{minipage}
% Finally, for the curious, here is how to draw the circular gluons in
% figure~\ref{fig:gluons}:
% \begin{verbatim}
% \fmfcmd{draw_gluon (fullcircle scaled .5w shifted (.5w,.5h));}
% \fmfcmd{draw_gluon (reverse fullcircle scaled .5w shifted (.5w,.5h));}
% \end{verbatim}
% \begin{figure}
% \begin{center}
% \begin{fmfchar}(40,40)
% \fmfcmd{draw_gluon (fullcircle scaled .5w shifted (.5w,.5h));}
% \end{fmfchar}
% \qquad
% \begin{fmfchar}(40,40)
% \fmfcmd{draw_gluon (reverse fullcircle scaled .5w shifted (.5w,.5h));}
% \end{fmfchar}
% \end{center}
% \caption{Circular gluons.}
% \label{fig:gluons}
% \end{figure}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Limitations}
% Currently the most severe limitation lies in the size of the
% generated pictures. The largest number \MF{} can represent
% internally is~4095.99998 and this is also the largest value any
% coordinate measured in pixels can assume. At the most popular
% laserprinter resolution of~300 dots per inch (dpi), this corresponds
% to a horizontal and vertical extension of about~346mm, which is
% plenty and we're more likely to hit the internal limits on the
% complexity of a picture. However, at the proof mode resolution
% of~2601.72dpi, this is reduced to slightly less than~40mm and we're
% running the risk of arithmetic overflow in internal calculations much
% earlier.
% There are two potential solutions of different scope and complexity:
% \begin{itemize}
% \item{} Since John Hobby's \MP{} is now available without a
% non-disclosure agreement from AT\&T, one solution is to replace
% \MF{} by \MP, which doesn't suffer from the size
% limitations\footnote{%
% Right now, \FMF's \MP{} support is still
% somewhat kludged, but the functionality is there.}
% This comes with a small price paid in reduced portability of the
% generated output, but as already stated above in the case of
% |axodraw|, the ubiquity of PostScript printers (and the free
% GhostScript interpreter) makes this a minor point.
% \item{} The more ambitious solutions will be ``virtual pictures''
% (see section~\ref{sec:virtual-pictures}).
% \end{itemize}
% \end{fmffile}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section*{Acknowledgements}
% I am most grateful to Wolfgang Kilian, who pushed \FMF's predecessor
% |feynman.mf| to its limits~\cite{Kil94}. His needs were valuable
% input to \FMF. Thanks also to Angelika Himmler and Uwe Mayer for
% acting as guinea pigs.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \begin{thebibliography}{99}
% \bibitem{TeX} Donald E.~Knuth, \textit{The \TeX{}book},
% Addison-Wesley, Reading, 1986.
% \bibitem{LaTeX} Leslie Lambort, \textit{\LaTeX{} --- A
% Documentation Preparation System},
% Addison-Wesley, Reading, 1985.
% \bibitem{LaTeX-Companion} Michel Goosens, Frank Mittelbach, and
% Alexander Samarin, \textit{The \LaTeX{} Companion},
% Addison-Wesley, Reading, 1994.
% \bibitem{MF} Donald E.~Knuth, \textit{The \MF{}book},
% Addison-Wesley, Reading, 1986.
% \bibitem{MetaPost} John D.~Hobby, \textit{A User's Manual for
% \MP}, Computer Science Report \#162, AT\&T Bell
% Laboratories, April 1992.
% \bibitem{hoenig} Alan Hoenig, \textit{When \TeX{} and \MF{}
% Work Together}, in \textit{Proceedings of the 7th European
% \TeX{} Conference, Prague}, p.~1, September 1992.
% \bibitem{levine} Micheal J.~S.~Levine,
% Comp.~Phys.~Comm.~\textbf{58} (1990) 181.
% \bibitem{axodraw} Jos Vermaseren, \texttt{axodraw}.
% \bibitem{mfpic} Thomas E.~Leathrum, \texttt{mfpic}.
% \bibitem{madgraph} Tim Stelzer and Bill Long, \texttt{MADGRAPH},
% hep-ph/93mmxxx.
% \bibitem{Kil94} Wolfgang Kilian, Doctoral Thesis, Technical
% University Darmstadt, 1994.
% \end{thebibliography}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \StopEventually{\PrintIndex\PrintChanges}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{\TeX{} macros}
% It's is good practice to identify this version of the document style
% option. We do this by parsing an RCS |Id| string and storing the
% result in the conventional \TeX{} control sequences:
% \changes{1.1}{1994/05/19}{%
% Don't loose on {\tt RCS} strings even iff the dollar signs have
% been removed.}
% \changes{1.9}{1995/02/18}{\LaTeX~2.09 compatibility}
% \begin{macrocode}
%<*style>
%<!209>\NeedsTeXFormat{LaTeX2e}
{\def\RCS#1#2\endRCS{%
\ifx$#1%
\@RCS $#2 \endRCS
\else
\@RCS $*: #1#2$ \endRCS
\fi}%
\def\@RCS $#1: #2,v #3 #4 #5 #6$ \endRCS{%
\gdef\filename{#2}%
\gdef\fileversion{v#3}%
\gdef\filedate{#4}%
\gdef\docdate{#4}}%
\RCS feynmf.dtx,v 1.10 1995/02/18 16:42:18 ohl Exp \endRCS}%
% \end{macrocode}
% And now the standard procedure:
% \changes{1.4}{1994/05/27}{%
% \MP{} support: identification part, include
% \texttt{graphicx} and pass options.}
% \begin{macrocode}
%<*!mp>
%<!209>\ProvidesPackage{feynmf}[\filedate\space LaTeX2e package]
\typeout{Package: `feynmf'
\fileversion\space <\filedate> (tho) PRELIMINARY TEST RELEASE}
\wlog{English documentation \@spaces<\docdate> (tho)}
%</!mp>
%<*mp>
%<!209>\ProvidesPackage{feynmp}[\filedate\space LaTeX2e package]
\typeout{Package: `feynmp'
\fileversion\space <\filedate> (tho) PRELIMINARY TEST RELEASE}
\wlog{English documentation \@spaces<\docdate> (tho)}
% \end{macrocode}
% Every option we don't understand (that is \emph{every} option) is
% sent down to |graphicx|:
% \begin{macrocode}
%<*!209>
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{graphicx}}
\ProcessOptions
% \end{macrocode}
% For the sake of Portabilitical Correctness, we use \LaTeX's
% |graphicx| for including PostScript, instead of the simpler |epsf|
% which comes with |dvips| and would have sufficed
% \begin{macrocode}
\RequirePackage{graphicx}
%</!209>
%<209>\input epsf.sty
%</mp>
% \end{macrocode}
% Compatibility macros for \LaTeX~2.09:
% \begin{macrocode}
%<*209>
\def\InputIfFileExists#1#2#3{%
\openin\@inputcheck#1 %
\ifeof\@inputcheck
\closein\@inputcheck
#3%
\else
\closein\@inputcheck
#2%
\input{#1}
\fi}
\def\IfFileExists#1#2#3{%
\openin\@inputcheck#1 %
\ifeof\@inputcheck
\closein\@inputcheck
#3%
\else
\closein\@inputcheck
#2%
\fi}
%</209>
% \end{macrocode}
% \begin{dubious}
% We should |\||mdqon| at the end only if the German extensions are
% really active, not just loaded.
% \end{dubious}
% \begin{macrocode}
\let\mdqrestore\relax
\@ifundefined{mdqoff}{}{%
\mdqoff
\let\mdqrestore\mdqon}
% \end{macrocode}
% \begin{macro}{\fmfcmd}
% The entrance through which our commands enter the world of
% \MF. Note the |\ignorespaces|: we need to avoid spurious
% blanks in the output list.
% \begin{macrocode}
\newwrite\@outfmf
\def\fmfcmd#1{%
\immediate\write\@outfmf{#1}\ignorespaces}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\fmffile}
% This environment encloses each \MF{} input file. The single
% argument gives the name of the file.
% \changes{1.1}{1994/05/16}{%
% Stupid: {\tt fileversion} can be reset by other packages, store
% the current value in {\tt fmf@fileversion} and use this one.}
% \changes{1.1}{1994/05/20}{%
% Pass RCS revision in a string.}
% \changes{1.4}{1994/05/27}{\MP{} support: write \MP{} file.}
% \changes{1.9}{1995/01/18}{%
% Protect against wrong arguments to \texttt{fmffile}.}
% \begin{macrocode}
{\catcode`\%=11\gdef\p@rcent{%}}
\edef\fmf@fileversion{\fileversion}
\def\fmffile#1{%
\def\thefmffile{#1}%
\equaltojobname{\thefmffile}{%
\errhelp={The argument of \fmffile MUST NOT be identical to the^^J%
name of your main input file! I will use fmfdefault.mf^^J%
this time around, but you'd better fix your code now!}%
\errmessage{Invalid arument of \string\fmffile!}%
\def\thefmffile{fmfdefault}}{}%
%<*!mp>
\immediate\openout\@outfmf=\thefmffile.mf\relax
\fmfcmd{\p@rcent\space \thefmffile.mf -- do not edit, %
generated automatically by \jobname.tex^^J%
input feynmf^^J%
require_RCS_revision "\expandafter\@gobble\fmf@fileversion";}%
%</!mp>
%<*mp>
\immediate\openout\@outfmf=\thefmffile.mp\relax
\fmfcmd{\p@rcent\space \thefmffile.mp -- do not edit, %
generated automatically by \jobname.tex^^J%
input feynmp^^J%
require_RCS_revision "\expandafter\@gobble\fmf@fileversion";}%
%</mp>
% \end{macrocode}
% The following trick has been taken from |mfpic|~\cite{mfpic}:
% proceed even if the font is not available yet, because we have to
% write the \MF{} file first.
% \changes{1.4}{1994/05/27}{\MP{} support: don't open \texttt{tfm} file.}
% \begin{macrocode}
%<*!mp>
\batchmode
\font\f@ynmf=\thefmffile
\errorstopmode
% \end{macrocode}
% Inform the user:
% \begin{macrocode}
\ifx\f@ynmf\nullfont
\def\f@ynmf{feynmf character:}%
\typeout{%
feynmf: File \thefmffile.tfm not found:^^J%
feynmf: Process \thefmffile.mf with METAFONT and then %
reprocess this file.}%
\else
\typeout{%
feynmf: File \thefmffile.tfm found.^^J%
feynmf: Nevertheless, if the picture has changed, %
reprocess \thefmffile.mf.^^J%
feynmf: If dimension have changed, reprocess \thefmffile.mf %
and \jobname.tex.}%
\fi
%</!mp>
% \end{macrocode}
% Count the characters
% \begin{macrocode}
\setcounter{fmfchar}{0}}
\let\thefmffile\relax
\newcounter{fmfchar}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\equaltojobname}
% Here's a kludge for comparing strings to |\jobname|. I dont quite
% understand, why the |\meaning| hack is necessary, but |\jobname|
% behaves differently from other macros with respect to |\ifx|.
% \begin{macrocode}
\def\equaltojobname#1#2#3{%
\edef\@tempa{#1}%
\edef\@tempa{\meaning\@tempa}%
\edef\@tempb{\jobname}%
\edef\@tempb{\meaning\@tempb}%
\ifx\@tempa\@tempb
#2
\else
#3
\fi}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\endfmffile}
% And here is how we close the |fmffile| environment:
% \begin{macrocode}
\def\endfmffile{%
\fmfcmd{\p@rcent\space the end.^^J%
end.^^J%
endinput;}%
\let\thefmffile\relax
\immediate\closeout\@outfmf}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\fmf@char}
% This is the bulk of the environment used for each ``character''
% drawn by \MF.
% \changes{1.5}{1994/08/17}{%
% Removed definiton of \texttt{sharp}. It's never used and
% conflicts with the $\sharp$ symbol.}
% \begin{macrocode}
{\catcode`\#=11\gdef\sh@rp{#}}
\def\fmf@char#1#2{%
% \end{macrocode}
% Make sure that a \MF{} file is open, otherwise \emph{really}
% obscure error messages are possible:
% \changes{1.3}{1994/05/23}{%
% Make sure that a \MF{} file is open, otherwise \emph{really}
% obscure error messages are possible.}
% \begin{macrocode}
\ifx\thefmffile\relax
\errhelp={Outside a fmffile environment, I have no clue as to where^^J%
the METAFONT commands should go. I will use fmfdefault.mf^^J%
for this character, but you'd better fix your code!}%
\errmessage{I detected a fmfchar environment outside of fmffile}%
\fmffile{fmfdefault}
\fi
% \end{macrocode}
% We can't use |\stepcounter| because of the |amstext| option of
% AMS-\LaTeX{} disables it sometimes.
% \changes{1.9}{1995/01/07}{Don't use \texttt{stepcounter}.}
% \begin{macrocode}
\global\expandafter\advance\csname c@fmfchar\endcsname \@ne
% \end{macrocode}
% Start \MF{} character:
% \begin{macrocode}
\fmfcmd{beginchar(\thefmfchar, #1*\the\unitlength\sh@rp, %
#2*\the\unitlength\sh@rp, 0);^^J%
"feynmf: \thefmfchar";}%
\fmfcmd{LaTeX_unitlength:=\the\unitlength;}%
\fmfinit
\fmfpen{thin}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\fmfchar}
% The plain version, no labels, no enclosing |picture| environment
% \begin{macrocode}
\def\fmfchar(#1,#2){%
\fmf@char{#1}{#2}%
% \end{macrocode}
% Place the character:
% \changes{1.4}{1994/05/27}{\MP{} support: include PostScript file.}
% \changes{1.9}{1995/02/18}{\LaTeX~2.09 compatibility}
% \begin{macrocode}
%<!mp>{\f@ynmf \char\value{fmfchar}}%
%<*mp>
\leavevmode
\IfFileExists{\thefmffile.\thefmfchar}%
%<*!209>
{\includegraphics[type=eps,ext=\thefmfchar,read=\thefmfchar]%
{\thefmffile}}%
%</!209>
%<*209>
{\epsffile{\thefmffile.\thefmfchar}}%
%</209>
{\typeout{%
feynmp: File \thefmffile.\thefmfchar\space not found:^^J%
feynmp: Process \thefmffile.mp with MetaPost and then %
reprocess this file.}}%
%</mp>
\ignorespaces}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\endfmfchar}
% \begin{macrocode}
\def\endfmfchar{%
\fmfposition
\fmfdraw
\fmfcmd{endchar;}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\fmfchar*}
% The extended version, with labels and |picture| environment.
% \begin{macrocode}
\@namedef{fmfchar*}(#1,#2){%
\begin{picture}(#1,#2)
\fmf@char{#1}{#2}%
% \end{macrocode}
% Process the \MF{} output for labels (if any), enforcing |%| as
% comment character.
% \begin{macrocode}
%<*!mp>
{\catcode`\%=14\relax
\grepfile{%
\thefmffile.\thefmfchar}{%
\thefmffile.log}{%
\thefmffile.t\thefmfchar}}%
%</!mp>
% \end{macrocode}
% Place the character:
% \changes{1.4}{1994/05/27}{\MP{} support: include PostScript file.}
% \begin{macrocode}
%<!mp>\put(0,0){{\f@ynmf \char\value{fmfchar}}}%
%<*mp>
\IfFileExists{\thefmffile.\thefmfchar}%
%<*!209>
{\put(0,0){\includegraphics[type=eps,ext=\thefmfchar,read=\thefmfchar]%
{\thefmffile}}}%
%</!209>
%<*209>
{\put(0,0){\epsffile{\thefmffile.\thefmfchar}}}%
%</209>
{\typeout{%
feynmp: File \thefmffile.\thefmfchar\space not found:^^J%
feynmp: Process \thefmffile.mp with MetaPost and then %
reprocess this file.}}%
%</mp>
\ignorespaces}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\endfmfchar*}
% \begin{macrocode}
\@namedef{endfmfchar*}{%
\endfmfchar
% \end{macrocode}
% Enforce |%| as comment character:
% \begin{macrocode}
{\catcode`\%=14\relax
\InputIfFileExists{\thefmffile.t\thefmfchar}{}{%
\typeout{%
feynmf: Label file \thefmffile.t\thefmfchar\space not found:^^J%
%<!mp> feynmf: Process \thefmffile.mf with METAFONT and then %
%<mp> feynmf: Process \thefmffile.mp with MetaPost and then %
reprocess this file.}}}%
\end{picture}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\fmfframe}
% This is used to allocate additional space around a |fmfchar*|, since
% the labels (or the diagram itself) might overshoot.
% |\fmfchar(|\meta{left}|,|\meta{top}|)(|\meta{right}|,|\meta{bottom}|){|%
% \meta{box}|}| puts an invisible frame of the given dimensions
% (measured in |\unitlength|) around \meta{box}.
% \begin{macrocode}
\def\fmfframe(#1,#2)(#3,#4)#5{%
\leavevmode
\hbox{\vbox{\vskip#2\unitlength\par
\hbox{\hskip#1\unitlength#5\hskip#3\unitlength}\par
\vskip#4\unitlength}}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\fmfpen}
% Picup a |pencircle| scaled by the argument.
% \begin{macrocode}
\def\fmfpen#1{\fmfcmd{pickup pencircle scaled #1;}}
% \end{macrocode}
% \end{macro}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Grep}
% \label{sec:grep}
% \begin{macro}{\grepfile}
% The macro |\grepfile{|\meta{pattern}|}{|\meta{in}|}{|\meta{out}|}|
% writes all lines matching |:|\meta{pattern}|:| from file \meta{in}
% to file \meta{out} after stripping off the pattern.
% \begin{dubious}
% Pattern matching on lines with a single leading colon fails.
% \end{dubious}
% \changes{1.4}{1994/05/28}{%
% Don't include the \texttt{grep} macros in the \MP{} version.
% \texttt{write} makes them obsolete.}
% \begin{macrocode}
%<*!mp>
\def\grepfile#1#2#3{%
\begingroup
% \end{macrocode}
% Hash the pattern and open the input and output streams:
% \begin{macrocode}
\edef\pattern{\csname*grep*#1*\endcsname}%
\immediate\openin\grep@infile #2\relax
\ifeof\grep@infile
\else
\grep@outopenfalse
% \end{macrocode}
% Don't add anything at the end of input lines and don't expand
% anything we've read from the file:
% \begin{macrocode}
\endlinechar=-1
\catcode`\\=12\relax
% \end{macrocode}
% Loop over the input lines until end of file occurs:
% \begin{macrocode}
\loop
\read\grep@infile to \grep@lbuf
\ifeof\grep@infile
\grep@contfalse
\else
\grep@conttrue
% \end{macrocode}
% Iff the input line is not empty, use |\grep@aline| to examine its
% contents and, iff the pattern matched, write a line to the output file.
% \begin{macrocode}
\ifx\grep@lbuf\empty
\else
\expandafter\grep@aline\grep@lbuf\sentinel
\ifx\pattern\grep@tag
% \end{macrocode}
% Delayed open (this avoids empty files):
% \begin{macrocode}
\ifgrep@outopen
\else
\immediate\openout\grep@outfile #3\relax
\immediate\write\grep@outfile{\p@rcent\space #3 %
-- generated automatically from #2}%
\immediate\write\grep@outfile{\p@rcent\space
Think twice before editing THIS file!}%
\grep@outopentrue
\fi
\immediate\write\grep@outfile{\grep@val}%
\fi
\fi
\fi
\ifgrep@cont
\repeat
% \end{macrocode}
% Close the files after we're done.
% \changes{1.1}{1994/05/16}{%
% Stupid: {\tt closein} the input stream, don't use {\tt closeout} on it.}
% \begin{macrocode}
\ifgrep@outopen
\immediate\closeout\grep@outfile
\fi
\fi
\immediate\closein\grep@infile
\endgroup}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\grep@infile}
% \begin{macro}{\grep@outfile}
% The I/O streams for the grep facility
% \begin{macrocode}
\newread\grep@infile
\newwrite\grep@outfile
% \end{macrocode}
% \end{macro}
% \end{macro}
% \begin{macro}{\ifgrep@cont}
% \begin{macro}{\ifgrep@outopen}
% and flags for the same
% \begin{macrocode}
\newif\ifgrep@cont
\newif\ifgrep@outopen
% \end{macrocode}
% \end{macro}
% \end{macro}
% \begin{macro}{\grep@aline}
% Examine one line and set the variables |\grep@tag| and |\grep@val|
% iff the line starts with a colon. Subtle point here: |\ifx#1:| will
% \emph{not} work if |#1| starts with a |{| followed by two identical
% characters.
% \begin{macrocode}
\def\grep@aline#1#2\sentinel{%
\ifx:#1%
\grep@splitlbuf#2\sentinel
\else
\edef\grep@tag{\csname*grep*\endcsname}%
\def\grep@val{}%
\fi}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\grep@splitlbuf}
% Split the line buffer at the remaining colon, hashing the first part.
% \begin{macrocode}
\def\grep@splitlbuf#1:#2\sentinel{%
\edef\grep@tag{\csname*grep*#1*\endcsname}%
\def\grep@val{#2}}
%</!mp>
% \end{macrocode}
% \end{macro}
% The other \TeX{} command sequences are defined below, along with the
% \MF{} macros they are in one-to-one correspondence to.
% \begin{macrocode}
%</style>
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{\MF{} macros}
% \label{sec:mf-code}
% Now we turn our attention to the \MF{}
% macros.
% \begin{dubious}
% We should find a way (a hack) to index the
% \MF{} macros with the |doc| option.
% \end{dubious}
% Because to name clashes, \FMF{} will not work if the |cmbase| is
% loaded. Die with an useful error message:
% \changes{1.5}{1994/06/13}{Don't accept the Computer Modern Base.}
% \begin{macrocode}
%<*base>
if known cmbase:
errhelp
"feynmf will only work with plain Metafont, as described in the book.";
errmessage "feynmf: CMBASE detected. Please use the PLAIN base.";
forever:
errmessage "No use in trying! You'd better eXit now ...";
errorstopmode;
endfor
% \end{macrocode}
% Make the RCS revision number available for feature testing:
% \changes{1.1}{1994/05/20}{%
% Handle arbitrary RCS revision strings.}
% \begin{macrocode}
vardef parse_RCS (suffix RCS) (expr s) =
save n, c;
numeric n, RCS[];
string c;
RCS[0] := 0;
for n = 1 upto length (s):
c := substring (n-1,n) of s;
exitif ((RCS[0] > 0) and (c = " "));
if ((c = "0") or (c = "1") or (c = "2")
or (c = "3") or (c = "4") or (c = "5")
or (c = "6") or (c = "7") or (c = "8")
or (c = "9")):
if RCS[0] = 0:
RCS[0] := 1;
RCS[RCS[0]] := 0;
fi
RCS[RCS[0]] := 10 * RCS[RCS[0]] + scantokens (c);
elseif c = ".":
RCS[0] := RCS[0] + 1;
RCS[RCS[0]] := 0;
else:
fi
endfor
enddef;
% \end{macrocode}
% Check that \LaTeX{} style and \MF{} macros are in sync:
% \begin{macrocode}
vardef require_RCS_revision expr s =
save n, TeX_rev, mf_rev;
numeric n;
parse_RCS (TeX_rev, s);
parse_RCS (mf_rev, "1.10");
for n = 1 upto min (2, TeX_rev[0], mf_rev[0]):
if TeX_rev[n] > mf_rev[n]:
errhelp
"Your version of `feynmf.sty' is higher that of your `feynmf.mf'.";
errmessage "feynmf: Metafont macros out of date";
elseif TeX_rev[n] < mf_rev[n]:
errhelp
"Your version of `feynmf.mf' is higher that of your `feynmf.sty'.";
errmessage "feynmf: LaTeX style out of date";
fi
exitif (TeX_rev[n] <> mf_rev[n]);
endfor
enddef;
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{\MP{} Kludges}
% This \MP{} support is still kludgey, but it works and we're trying
% to prove a point.
% \changes{1.4}{1994/05/27}{Preliminary \MP{} support: mimic \MF.}
% \begin{macrocode}
%<*mp>
vardef cullit = \ enddef;
% \end{macrocode}
% \begin{macrocode}
vardef beginchar (expr c, wd, ht, dp) =
LaTeX_file := "";
beginfig(c);
w:=wd;
h:=ht;
enddef;
string LaTeX_file;
% \end{macrocode}
% \begin{macrocode}
vardef endchar =
setbounds currentpicture to (0,0)--(w,0)--(w,h)--(0,h)--cycle;
if LaTeX_file <> "":
write EOF to LaTeX_file;
LaTeX_file := "";
endfig
enddef;
% \end{macrocode}
% Sharped dimensions are useless with \MP. We define them anyway
% with trivial translation, so that the \MF{} code can be used
% unchanged.
% \begin{macrocode}
bp# := bp;
cc# := cc;
cm# := cm;
dd# := dd;
in# := in;
mm# := mm;
pc# := pc;
pt# := pt;
% \end{macrocode}
% As I said: trivial translation.
% \begin{macrocode}
vardef define_blacker_pixels(text t) =
forsuffixes $=t:
$:=$.#;
endfor
enddef;
%</mp>
% \end{macrocode}
% \begin{macrocode}
%<!mp>mode_setup;
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Basics}
% \label{sec:mf-basics}
% Allow the user to life dangerously or not, depending on his
% preferences.
% \changes{1.7}{1994/10/23}{\texttt{fmfwizard}: to live dangerously or not.}
% \begin{macrocode}
boolean feynmfwizard;
feynmfwizard := false;
%</base>
% \end{macrocode}
% \begin{macro}{\fmfwizard}
% \begin{macro}{\fmfnowizard}
% \begin{macrocode}
%<*style>
\def\fmfwizard{\fmfcmd{feynmfwizard := true;}}
\def\fmfnowizard{\fmfcmd{feynmfwizard := false;}}
%</style>
% \end{macrocode}
% \end{macro}
% \end{macro}
% Default values of style parameters:
% \begin{macrocode}
%<*base>
thin#:=1pt#; % dimension of the lines
thick#:=2thin#;
arrow_len# := 4mm#;
arrow_ang := 15;
curly_len#:=3mm#;
dash_len#:=3mm#; % 'photon' lines
dot_len#:=2mm#; % 'photon' lines
wiggly_len#:=4mm#; % 'photon' lines
wiggly_slope:=60;
shade_black#:=1pt#; % shading
shade_white#:=2shade_black#;
shade_angle:=60;
decor_size#:=5mm#;
dot_size#:=2thick#;
% \end{macrocode}
% Convert ``sharp'' units:
% \begin{macrocode}
define_blacker_pixels (thick, thin, shade_black, shade_white,
dash_len, dot_len, wiggly_len, curly_len, arrow_len,
decor_size, dot_size);
% \end{macrocode}
% Back by popular demand: shrinking dimensions.
% \changes{1.5}{1994/06/13}{%
% Back by popular demand: shrinking dimensions.}
% \begin{macrocode}
def shrink expr s =
begingroup
if shrinkables <> "":
save tmp_;
forsuffixes $ = scantokens shrinkables:
tmp_ := $.#;
save $;
$.# := s * tmp_;
endfor
define_blacker_pixels (scantokens shrinkables);
enddef;
% \end{macrocode}
% \begin{macrocode}
def endshrink =
endgroup
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmfshrink}
% \begin{macro}{\endfmfshrink}
% Exporting the whole enchilada to \LaTeX:
% \begin{macrocode}
%<*style>
\def\fmfshrink#1{\fmfcmd{shrink (#1);}}
\def\endfmfshrink{\fmfcmd{endshrink;}}
%</style>
% \end{macrocode}
% \end{macro}
% \end{macro}
% \begin {macrocode}
%<*base>
string shrinkables;
shrinkables := "";
% \end{macrocode}
% This macro is used to register shrinkable dimensions. It is not
% really robust, we have add the first enty by hand:
% \begin {macrocode}
vardef addto_shrinkables (text l) =
forsuffixes $ = l:
shrinkables := shrinkables & "," & str $;
endfor
enddef;
shrinkables := "thick,thin";
% \end{macrocode}
% \begin {macrocode}
addto_shrinkables (shade_black, shade_white);
addto_shrinkables (dash_len, dot_len);
addto_shrinkables (wiggly_len, curly_len);
addto_shrinkables (arrow_len);
addto_shrinkables (decor_size, dot_size);
% \end{macrocode}
% Default to metric units, but this will be reset by |\begin{fmfchar}|
% anyway.
% \begin {macrocode}
LaTeX_unitlength := mm;
% \end{macrocode}
% Count the number of tokens in the argument:
% \begin {macrocode}
vardef count (text list) =
forsuffixes $ = list: + 1 endfor
enddef;
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Parsing options}
% \label{sec:getopt}
% Parse the string |s| into comma separated tokens |opt[]|, ignoring
% blanks before |=|'s. Double commas are passed as a single comma.
% \changes{1.9}{1994/10/25}{%
% Plugged the string memory leak in \texttt{getopt}: don't create
% intermediate one character strings, \MF{} never claims them back.}
% \begin {macrocode}
vardef getopt (suffix opt) (expr s) =
save n, argp, escape, anchor, skip;
numeric opt.first, opt.last, n, anchor;
string opt[], opt[]arg;
boolean opt[]tainted, argp, escape, skip;
opt.first := 0;
opt.last := 0;
opt[opt.last] := "";
argp := false;
escape := false;
anchor := 0;
skip := true;
for n = 1 upto length (s):
% \end{macrocode}
% Skip blanks at the beginning of each option or argument:
% \begin {macrocode}
if skip and (substring (n-1, n) of s = " "):
anchor := anchor + 1;
else:
skip := false;
% \end{macrocode}
% If we see a comma which has not been escaped, check for a second
% comma and set the |escape| flags and remember to remove the second
% comma later or reset the |argp| flag, as appropriate:
% \begin {macrocode}
if not escape and (substring (n-1, n) of s = ","):
if substring (n, n+1) of s = ",":
escape := true;
opt[opt.last]tainted := true;
% \end{macrocode}
% Else accept the option or argument:
% \begin {macrocode}
else:
if argp:
opt[opt.last]arg := substring (anchor, n-1) of s;
else:
opt[opt.last] := substring (anchor, n-1) of s;
fi
anchor := n;
argp := false;
skip := true;
opt.last := opt.last + 1;
fi
% \end{macrocode}
% Start as argument and ignore |=|'s until the next option:
% \begin {macrocode}
elseif not argp and (substring (n-1, n) of s = "="):
opt[opt.last] := substring (anchor, n-1) of s;
anchor := n;
argp := true;
skip := true;
% \end{macrocode}
% Accept the next character (either option or argument) and reset the
% |escape| flag:
% \begin {macrocode}
elseif argp or (substring (n-1, n) of s <> " "):
escape := false;
fi
fi
endfor
% \end{macrocode}
% Accept the final option or argument:
% \begin {macrocode}
if argp:
opt[opt.last]arg := substring (anchor, length s) of s;
else:
opt[opt.last] := substring (anchor, length s) of s;
% \end{macrocode}
% We still have to remove possible doubled commata from the arguments.
% Theoretically, we could already have done it above (that's the way
% earlier versions of \FMF{} did it), but only at the expense of
% excessive copying of strings (like |opt[n]arg:=opt[n]arg&c|). Given
% \MF's string handling, we should avoid these \emph{at any cost},
% because the wasted string memory will \emph{never} be
% reclaimed!\footnote{Actually, \MP{} has code to compact the string
% pool, which makes \emph{a lot} of difference in the present case.
% But this doesn't help us with \MF.}
% Since the more elegant former version had a serious string memory
% leak, we'd better stick to the current ugly but space efficient
% implementation.
% \begin {macrocode}
for n = opt.first upto opt.last:
if known opt[n]tainted:
if opt[n]tainted:
opt[n]arg := untaint_string opt[n]arg;
fi
fi
endfor
enddef;
% \end{macrocode}
% Turn double commata into single commata, using as little string
% copies as possible:
% \begin {macrocode}
vardef untaint_string suffix s =
save n, anchor;
numeric n, anchor;
anchor := 0;
for n = 1 upto length (s) - 1:
if substring (n-1,n+1) of s = ",,":
substring (anchor, n-1) of s &
hide (anchor := n)
fi
endfor
substring (anchor, length s) of s
enddef;
% \end{macrocode}
% Split a string into |.|-separated components for matching options.
% \begin {macrocode}
vardef split_string (suffix comp) (expr s) =
save n, anchor;
numeric comp.first, comp.last, n, anchor;
string comp[];
comp.first := 0;
comp.last := 0;
comp[comp.last] := "";
anchor := 0;
for n = 1 upto length (s):
if substring (n-1,n) of s = ".":
comp[comp.last] := substring (anchor, n-1) of s;
comp.last := comp.last + 1;
anchor := n;
fi
endfor
comp[comp.last] := substring (anchor, length s) of s;
enddef;
% \end{macrocode}
% Return |true| iff |prefix| is a prefix of |s|:
% \begin {macrocode}
vardef match_prefix (expr prefix, s) =
(prefix = substring (0, length prefix) of s)
enddef;
% \end{macrocode}
% Match options similarly to |Xt| resource strings, but allowing for
% abbreviations:
% \changes{1.7}{1994/10/23}{More general option parsing.}
% \begin {macrocode}
vardef match_option (expr s, option) =
save sc, optionc, n, i;
numeric sc.first, sc.last, optionc.first, optionc.last;
string sc[], optionc[];
numeric n, i;
split_string (sc, s);
split_string (optionc, option);
n := sc.last - sc.first;
if n <> (optionc.last - optionc.first):
false
else:
true
for i = 0 upto n:
and match_prefix (sc[sc.first+i],
optionc[optionc.first+i])
endfor
enddef;
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Manipulating \texttt{picture}s}
% \label{sec:pictures}
% |save_picture (list_of_pictures)| |save|'s each member of
% |list_of_pictures| inside a group and reinitializes them as nullpictures.
% \begin{macrocode}
def save_picture text t =
save t; picture t; forsuffixes p=t: p:=nullpicture; endfor
enddef;
% \end{macrocode}
% |begin_sketch| pushes the sketchpad stack and perform the following
% drawing commands (upto the next |end_sketch|) on the new sketchpad.
% \begin{macrocode}
def begin_sketch =
begingroup save_picture currentpicture;
sketchlevel := sketchlevel+1;
enddef;
% \end{macrocode}
% |end_sketch| pops the sketchpad stack.
% \begin{macrocode}
def end_sketch =
sketchlevel := sketchlevel-1;
sketchpad[sketchlevel] := currentpicture;
endgroup
enddef;
% \end{macrocode}
% \begin{macrocode}
picture sketchpad[];
sketchlevel := 1;
% \end{macrocode}
% |use_sketch (transformation)| copies the transformed sketchpad into
% the current picture.
% \begin{macrocode}
vardef use_sketch text t =
addto currentpicture also (sketchpad[sketchlevel] t)
enddef;
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Shading}
% \label{sec:shading}
% |shade (path_arg)| shades the interior of |path_arg|. This shading is
% controlled by the global variables |shade_black|, |shade_white|, and
% |shade_angle|.
% Caveat: The procedure is only guaranteed to work for convex paths.
% \begin{dubious}
% \MP{} has nice primitives to aid in finding bounding boxes, in
% \MF{} we have to rely on heuristics.
% \end{dubious}
% \begin{macrocode}
vardef shade expr p_arg =
save x,y,d,p,currentpen; path p; pen currentpen; % push pen!
pickup pencircle scaled shade_black;
p = p_arg rotated - shade_angle; % calculate enclosing rectangle
x2' = x3' = xpart directionpoint up of p; % (rotated by |shade_angle|).
x1' = x4' = xpart directionpoint down of p;
y1' = y2' = ypart directionpoint right of p;
y3' = y4' = ypart directionpoint left of p;
forsuffixes $=1,2,3,4: z$ = z$' rotated shade_angle; endfor
d = abs(z1-z4); % height.
begin_sketch % fill rectangle with lines.
for k=shade_white/d step (shade_white+shade_black)/d
until 1 - shade_white/d:
cutdraw k[z1,z4] -- k[z2,z3];
endfor
% \end{macrocode}
% \MF{} has no clipping operation, but since we know the bounding box,
% we can use \MF's pixel arithmetic for calculating the set
% theoretical intersection of the interior of |p_arg| and the diagonal
% lines in the bounding box:
% \begin{macrocode}
%<*!mp>
cullit;
fill p_arg;
unfill z1--z2--z3--z4--cycle;
cullit;
%</!mp>
% \end{macrocode}
% \MP{} has clipping build in but no pixel arithmetic:
% \changes{1.4}{1994/05/28}{\MP{} support: shading.}
% \begin{macrocode}
%<*mp>
clip currentpicture to p_arg;
%</mp>
end_sketch;
use_sketch;
enddef;
% \end{macrocode}
% Hatching is implemented as double shading.
% \changes{1.7}{1994/10/22}{Hatched vertices.}
% \begin{macrocode}
vardef hatch expr p =
shade p;
save a;
a = shade_angle;
save shade_angle;
shade_angle = a + 90;
shade p;
enddef;
% \end{macrocode}
% |filldraw|'s sisters:
% \begin{macrocode}
vardef shadedraw expr p =
shade p;
draw p;
enddef;
vardef hatchdraw expr p =
hatch p;
draw p;
enddef;
% \end{macrocode}
% John Hobby has a particulary nice |arrowhead| macro in plain \MP. A
% variation on that theme adapted to our needs is:
% \changes{1.5}{1994/10/20}{New arrows, which look better on curved arcs.}
% \begin{macrocode}
vardef arrow expr p =
save t, a, z_, ap_, tip;
numeric t[], a;
pair z_, tip;
path ap_;
a = angle direction .5 length(p) of p;
z_ = point .5 length(p) of p;
(t1,whatever) = p intersectiontimes
(halfcircle scaled 2/3arrow_len rotated (a+90) shifted z_);
(t2,whatever) = p intersectiontimes
(halfcircle scaled 4/3arrow_len rotated (a-90) shifted z_);
% \end{macrocode}
% |intersectiontimes| can fail, typically if the path is too short:
% protect against it
% \changes{1.6}{1994/10/21}{Fix arrows on too short arcs.}
% \begin{macrocode}
if t1 = -1: t1 := 0; fi
if t2 = -1: t2 := length p; fi
tip = point t2 of p;
ap_ = subpath (t1,t2) of p shifted -tip;
(ap_ rotated arrow_ang
forced_join reverse ap_ rotated -arrow_ang
-- cycle) shifted tip
enddef;
% \end{macrocode}
% Join two paths |p| and |q| even if they don't fit exactly by
% adjusting their common point. This is necessary in |arrow| because
% rounding errors might induce a small mismatch even if we \emph{know}
% that they should match theoretically. This is certainly a kludge
% and should be used with care, but it works.
% \begin{macrocode}
tertiarydef p forced_join q =
subpath (0, length p - 1) of p
& point (length p - 1) of p
.. controls postcontrol (length p - 1) of p
and precontrol infinity of p
.. .5[point infinity of p, point 0 of q]
.. controls postcontrol 0 of q and precontrol 1 of q
.. point 1 of q
& subpath (1, infinity) of q
enddef;
% \end{macrocode}
% |cut_decors| expands to a subpath of |path_arg|, excluding the
% decoration at the vertices.
% \changes{1.7}{1994/10/22}{Cut general vertex decorations.}
% \begin{macrocode}
vardef cut_decors (suffix from) (expr p) (suffix to) =
subpath (if known from.decor.shape:
xpart (p intersectiontimes
(from.decor.shape scaled from.decor.size
shifted from.loc))
else:
0
fi,
if known to.decor.shape:
xpart (p intersectiontimes
(to.decor.shape scaled to.decor.size
shifted to.loc))
else:
infinity
fi) of p
enddef;
% \end{macrocode}
% The function |make_blob| is the working horse of |draw_blob|.
% \begin{macrocode}
vardef make_blob (expr z_arg, diameter) =
save p,currentpen; path p; pen currentpen;
pickup pencircle scaled thick;
p = fullcircle scaled diameter shifted z_arg;
shadedraw p;
enddef;
% \end{macrocode}
% |draw_blob (pair_arg, diameter)| draws a shaded blob of diameter
% |diameter| centered at |pair_arg|. The thickness of the border is
% controlled by the global variable |thick|.
% Hint: It saves time to draw blobs of the same size in sequence.
% \begin{macrocode}
vardef draw_blob (expr z_arg, diameter) =
if sketched_blob_diameter <> diameter: % drawn lately?
begin_sketch make_blob (origin, diameter); end_sketch; % redo hard work!
sketched_blob_diameter:= diameter; % record it
use_sketch shifted z_arg; % the easy way ...
enddef;
% \end{macrocode}
% |force_new_blob| forces the redrawing of a blob of the same diameter
% (in case you only changed the shading parameters).
% \begin{macrocode}
def force_new_blob = sketched_blob_diameter := -1; enddef;
force_new_blob; % initialize it.
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Drawing}
% \label{sec:drawing}
% Easier than
% \begin{equation}
% \int_0^1 dt \left\vert\frac{dx(t)}{dt}\right\vert
% \end{equation}
% with the integrand the square root of a fourth order polynomial, but
% sufficient for all practical purposes is
% \begin{macrocode}
vardef pixlen (expr p, n) =
for k=1 upto length(p): + segment_pixlen (subpath (k-1,k) of p, n) endfor
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef segment_pixlen (expr p, n) =
for k=1 upto n: + abs (point k/n of p - point (k-1)/n of p) endfor
enddef;
% \end{macrocode}
% |wiggly (path_arg)| expands to a ``wiggled'' version of |path_arg|. The
% slope of the wiggles is controlled by the global variable |wiggle_slope|,
% the length of the wiggles by the global variable |wiggly_len|.
% \begin{macrocode}
vardef wiggly expr p_arg =
save wpp;
numeric wpp;
wpp = ceiling (pixlen (p_arg, 10) / (wiggly_len * length(p_arg)));
for k=0 upto wpp*length(p_arg) - 1:
point k/wpp of p_arg
{direction k/wpp of p_arg rotated wiggly_slope} ..
point (k+.5)/wpp of p_arg
{direction (k+.5)/wpp of p_arg rotated - wiggly_slope} ..
endfor
if cycle p_arg: cycle else: point infinity of p_arg fi
enddef;
% \end{macrocode}
% |curly (path_arg)| expands to a ``curly'' version of |path_arg|. The
% the length of the curls is controlled by the global variable
% |curly_len|.
% \begin{macrocode}
vardef curly expr p_arg =
save cpp;
numeric cpp;
cpp = ceiling (pixlen (p_arg, 10) / (curly_len * length(p_arg)));
if cycle p_arg:
for k=0 upto cpp*length(p_arg) - 1:
point (k+.33)/cpp of p_arg
{direction (k+.33)/cpp of p_arg rotated 90} ..
point (k-.33)/cpp of p_arg
{direction (k-.33)/cpp of p_arg rotated -90} ..
endfor
cycle
else:
point 0 of p_arg
{direction 0 of p_arg rotated -90} ..
for k=1 upto cpp*length(p_arg) - 1:
point (k+.33)/cpp of p_arg
{direction (k+.33)/cpp of p_arg rotated 90} ..
point (k-.33)/cpp of p_arg
{direction (k-.33)/cpp of p_arg rotated -90} ..
endfor
point infinity of p_arg
{direction infinity of p_arg rotated 90}
enddef;
% \end{macrocode}
% An inventory of valid line styles is implemented as a hash table:
% \begin{macrocode}
save vsty_hash;
% \end{macrocode}
% This is a bit like |mode_def| in plain \MF{} but doesn't use an
% array of available modes: |style_def "foo"| will define a macro
% |draw_foo| drawing a line of a certain style along any given path:
% \begin{macrocode}
def style_def suffix s =
vsty_hash.s := 1;
expandafter quote vardef scantokens ("draw_" & str s)
enddef;
% \end{macrocode}
% Let \MF{} do the lookup: suffices
% \begin{macrocode}
vardef vsty_exists suffix s =
known vsty_hash.s
enddef;
% \end{macrocode}
% an strings
% \begin{macrocode}
vardef valid_style expr s =
expandafter vsty_exists scantokens (s)
enddef;
% \end{macrocode}
% \changes{1.9}{1994/11/21}{Enhance and streamline the line styles.}
% |phantom| lines are simple, even with arrows.
% \begin{macrocode}
style_def phantom expr p =
enddef;
style_def phantom_arrow expr p =
fill (arrow p);
enddef;
% \end{macrocode}
% |plain| lines aren't harder.
% \begin{macrocode}
style_def plain expr p =
draw p;
enddef;
style_def plain_arrow expr p =
draw p;
fill (arrow p);
enddef;
style_def dbl_plain expr p =
draw_double p;
enddef;
style_def dbl_plain_arrow expr p =
draw_double_arrow p;
enddef;
% \end{macrocode}
% Wiggly lines use |wiggly| from above
% \begin{macrocode}
style_def wiggly expr p =
draw (wiggly p);
enddef;
style_def dbl_wiggly expr p =
draw_double (wiggly p);
enddef;
% \end{macrocode}
% and curly lines use |curly| from above
% \begin{macrocode}
style_def curly expr p =
draw (curly p);
enddef;
style_def dbl_curly expr p =
draw_double (curly p);
enddef;
% \end{macrocode}
% |draw_dashes (p)| draws a dashed line on |p|
% \changes{1.4}{1994/05/27}{%
% Rename the line style \texttt{dashed} to \texttt{dashes}, to avoid
% a name clash with \MP.}
% \begin{macrocode}
style_def dashes expr p_arg =
save dpp;
numeric dpp;
dpp = ceiling (pixlen (p_arg, 10) / (dash_len * length(p_arg)));
for k=0 upto dpp*length(p_arg) - 1:
draw point k/dpp of p_arg ..
point (k+.5)/dpp of p_arg;
endfor
enddef;
style_def dbl_dashes expr p =
save dpp;
numeric dpp;
dpp = ceiling (pixlen (p, 10) / (dash_len * length(p)));
for k=0 upto dpp*length(p) - 1:
draw_double point k/dpp of p ..
point (k+.5)/dpp of p;
endfor
enddef;
style_def dbl_dashes_arrow expr p =
draw_dbl_dashes p;
fill (arrow p);
enddef;
style_def dashes_arrow expr p =
draw_dashes p;
fill (arrow p);
enddef;
% \end{macrocode}
% |draw_dots (expr p_arg)| draws a dotted line on |path_arg|
% \changes{1.4}{1994/05/27}{%
% Rename the line style \texttt{dotted} to \texttt{dots}, to be
% consistent with \texttt{dashes}.}
% \begin{macrocode}
style_def dots expr p_arg =
save dpp;
numeric dpp;
dpp = ceiling (pixlen (p_arg, 10) / (dot_len * length(p_arg)));
for k=0 upto dpp*length(p_arg):
drawdot point k/dpp of p_arg;
endfor
enddef;
style_def dbl_dots expr p_arg =
save dpp;
numeric dpp;
dpp = ceiling (pixlen (p_arg, 10) / (dot_len * length(p_arg)));
begingroup
pen oldpen;
oldpen := currentpen;
pickup oldpen scaled 3; % draw a thick linn
for k=0 upto dpp*length(p_arg):
drawdot point k/dpp of p_arg;
endfor
pickup oldpen;
cullit;
for k=0 upto dpp*length(p_arg):
undrawdot point k/dpp of p_arg;
endfor
cullit; % and remove the stuffing
endgroup;
enddef;
style_def dbl_dots_arrow expr p =
draw_dbl_dots p;
fill (arrow p);
enddef;
style_def dots_arrow expr p =
draw_dots p;
fill (arrow p);
enddef;
% \end{macrocode}
% |draw_double (expr p_arg)| draws a double line.
% \begin{macrocode}
style_def double expr p_arg =
begingroup
pen oldpen;
oldpen := currentpen;
pickup oldpen scaled 3; % draw a thick linn
draw p_arg;
pickup oldpen;
cullit; undraw p_arg; cullit; % and remove the stuffing
endgroup;
enddef;
style_def double_arrow expr p =
draw_double p;
fill (arrow p);
enddef;
% \end{macrocode}
% Old aliases:
% \begin{macrocode}
style_def vanilla expr p = draw_plain p enddef;
style_def fermion expr p = draw_plain_arrow p enddef;
style_def quark expr p = draw_plain_arrow p enddef;
style_def electron expr p = draw_plain_arrow p enddef;
style_def photon expr p = draw_wiggly p enddef;
style_def boson expr p = draw_wiggly p enddef;
style_def gluon expr p = draw_curly p enddef;
style_def heavy expr p = draw_dbl_plain_arrow p enddef;
style_def ghost expr p = draw_dots_arrow p enddef;
style_def scalar expr p = draw_dashes_arrow p enddef;
% \end{macrocode}
% More old aliases:
% \begin{macrocode}
vardef fermion expr path_arg =
fill arrow (path_arg);
path_arg
enddef;
vardef photon expr path_arg =
wiggly path_arg
enddef;
vardef gluon expr path_arg =
curly path_arg
enddef;
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Graphs of vertices}
% \label{sec:graphs}
% Here is the fun part of \FMF: \emph{automagic} placement of
% vertices.
% \begin{macrocode}
%tracingmacros:=1;
%tracingonline:=1;
tracingstats:=1;
% \end{macrocode}
% You can say |vtracing:=true| to see what's going on.
% \begin{macrocode}
boolean vtracing;
vtracing := false; % true
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Data structures}
% \begin{table}
% \begin{tabular}{lll}
% Type & Name & Purpose \\\hline
% |numeric| & |vlist.first| & pointer to first vertex (usually 1) \\
% |numeric| & |vlist.last| & pointer to last vertex (starts with 0) \\
% |string| & |vlist[|$i$|]name| & symbolic name of the vertex\\
% |pair| & |vlist[|$i$|]loc| & position of the vertex \\
% |string| & |vlist[|$i$|]lbl| & label \\
% |numeric| & |vlist[|$i$|]lbl.ang| & angle \\
% |numeric| & |vlist[|$i$|]lbl.dist| & distance \\
% |path| & |vlist[|$i$|]decor.shape| & shape of decoration\\
% |numeric| & |vlist[|$i$|]decor.size| & size of decoration\\
% |numeric| & |vlist[|$i$|]decor.sty| & filling style of decoration\\
% |numeric| & |vlist[|$i$|]decor.ang| & rotation angle\\
% |numeric| & |vlist[|$i$|]arc.first| & pointer to first arc \\
% |numeric| & |vlist[|$i$|]arc.last| & pointer to last arc \\
% |numeric| & |vlist[|$i$|]arc[|$j$|]| & $j$th arc of the $i$th vertex \\
% |string| & |vlist[|$i$|]arc[|$j$|]sty| & style of the arc\\
% |numeric| & |vlist[|$i$|]arc[|$j$|]tns| & tension of the arc\\
% |string| & |vlist[|$i$|]arc[|$j$|]lsr| & left, straight, right\\
% |string| & |vlist[|$i$|]arc[|$j$|]lbl| & label\\
% |string| & |vlist[|$i$|]arc[|$j$|]lbl.side|& side of the label\\
% |numeric| & |vlist[|$i$|]arc[|$j$|]lbl.dist|& distance of the label
% \end{tabular}
% \caption{Vertex data structure}
% \label{tab:VDS}
% \end{table}
% The data structure for our graph is shown in
% table~\ref{tab:VDS}\footnote{%
% \begin{dubious}
% \texttt{boolean vlist[i]arc[j]smooth} will indicate that this
% arc belongs to a set of arcs which are to be smoothly connected.
% The implementation will start by going to the strt of this set,
% define a long smooth path and finally do the drawing on the
% various subpaths.
% \end{dubious}}.
% \MF{} turns out to be quite powerful, providing such constructs
% in an unconventional, but flexible and concise way. While we use
% |save vhash| to forget all previously defined vertices, we leave
% |vlist| alone, because we will know from $|vlist.last| <
% |vlist.first|$ that it's empty. Note that we can't |vardef| this
% because then the |save| would go inside a group.
% \begin{macrocode}
def vinit =
save vhash;
numeric vlist.first, vlist.last;
vlist.first := 1;
vlist.last := 0;
pair vlist[]loc, lambda[][];
numeric vlist[]decor.size, vlist[]decor.sty, vlist[]decor.ang,
vlist[]arc.first, vlist[]arc.last,
vlist[]arc[], vlist[]arc[]lsr,
vlist[]arc[]tns, vlist[]arc[]lbl.dist,
vlist[]constr.first, vlist[]constr.last,
vlist[]constr[];
string vlist[]name, vlist[]lbl,
vlist[]arc[]sty, vlist[]arc[]lbl, vlist[]arc[]lbl.side;
numeric vlist[]lbl.ang, vlist[]lbl.side;
path vlist[]decor.shape;
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmfinit}
% We can also ask for initialization explicitely from \TeX{} (usually
% it is called implicitely by |\begin{fmfchar}|). This flushes the
% vertex table.
% \begin{macrocode}
%<style>\def\fmfinit{\fmfcmd{vinit;}}
% \end{macrocode}
% \end{macro}
% Useful abstractions are: first for looping over all vertices
% \begin{macrocode}
%<*base>
def vertices =
vlist.first upto vlist.last
enddef;
% \end{macrocode}
% second for looping over all arcs of vertex |i|
% \begin{macrocode}
def varcs (text i) =
vlist[i]arc.first upto vlist[i]arc.last
enddef;
% \end{macrocode}
% and finally for looping over all constraints of vertex |i|
% \begin{macrocode}
def vconstr (text i) =
vlist[i]constr.first upto vlist[i]constr.last
enddef;
% \end{macrocode}
% Entering vertices is simple, but note that we have to make
% |vlist[|$i$|]loc| undefined, because it might be around from an
% earlier character still.
% \begin{macrocode}
vardef venter suffix v =
if not vexists v:
vlist.last := vlist.last + 1;
vhash.v := vlist.last;
vlist[vhash.v]name := str v;
vlist[vhash.v]loc := (whatever,whatever);
vlist[vhash.v]arc.first := 1;
vlist[vhash.v]arc.last := 0;
vlist[vhash.v]constr.first := 1;
vlist[vhash.v]constr.last := 0;
vlist[vhash.v]lbl := "";
vlist[vhash.v]lbl.ang := whatever;
vlist[vhash.v]lbl.dist := 3;
enddef;
% \end{macrocode}
% The next three \emph{are} trivial. Existence
% \begin{macrocode}
vardef vexists suffix v =
if known vhash.v: true else: false fi
enddef;
% \end{macrocode}
% index
% \begin{macrocode}
vardef vlookup suffix v =
if vexists v: vhash.v else: 0 fi
enddef;
% \end{macrocode}
% and location
% \begin{macrocode}
vardef vloc suffix v =
vlist[vlookup v]loc
enddef;
% \end{macrocode}
% of vertices. We use |vhash.v| instead of |v| so that we can clear
% the whole hash table with |save vhash|.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Constructing the Graph}
% Connect the vertices in the list |vl| with lines of style |style|,
% allocating them if necessary.
% \begin{dubious}
% Be more flexible about whether adding arrows
% or not. This should be implemented using the options and devising
% a path filter mechanism.
% \end{dubious}
% \begin{macrocode}
vardef vconnect (expr linesty) (text vl) =
save from, nfrom, nto, nopt, sty;
numeric from, nfrom, nto, nopt;
string sty;
getopt (opt, linesty);
sty := opt[opt.first];
if known opt[opt.first]arg:
message "feynmf: line styles don't take arguments. "
& "Argument `" & opt[opt.first]arg & "' ignored.";
opt.first := opt.first + 1;
forsuffixes to = vl:
venter to;
nto := vlookup to;
if known nfrom:
% \end{macrocode}
% Later, on page~\pageref{pg:vposition}, it will pay back to enter the
% arc \emph{both} ways: incoming \emph{and}
% outgoing:\label{pg:vconnect}
% \begin{macrocode}
vlist[nfrom]arc.last := vlist[nfrom]arc.last + 1;
vlist[nto]arc.last := vlist[nto]arc.last + 1;
vlist[nfrom]arc[vlist[nfrom]arc.last] := nto;
vlist[nto]arc[vlist[nto]arc.last] := nfrom;
vlist[nfrom]arc[vlist[nfrom]arc.last]tns := 1;
vlist[nto]arc[vlist[nto]arc.last]tns := 1;
vlist[nfrom]arc[vlist[nfrom]arc.last]lsr := 0;
vlist[nfrom]arc[vlist[nfrom]arc.last]lbl := "";
vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.side := "";
vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.dist := 3;
% \end{macrocode}
% Handle options, starting with an option |tension|:
% \begin{macrocode}
for nopt = opt.first upto opt.last:
if match_option (opt[nopt], "tension"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[nfrom]arc[vlist[nfrom]arc.last]tns);
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[nto]arc[vlist[nto]arc.last]tns);
% \end{macrocode}
% Handle |left|, |straight| and |right|, which ask for making a
% halfcircle detour on the specified side or going straight. If given
% an optional argument, the halfcircle is pulled in or pushed out,
% according whether it is smaller or larger than 1.
% \changes{1.5}{1994/10/20}{Accept optional argument for detours.}
% \begin{macrocode}
elseif match_option (opt[nopt], "left"):
if known opt[nopt]arg:
vlist[nfrom]arc[vlist[nfrom]arc.last]lsr
:= - scantokens (opt[nopt]arg);
else:
vlist[nfrom]arc[vlist[nfrom]arc.last]lsr := -1;
fi
elseif match_option (opt[nopt], "straight"):
vlist[nfrom]arc[vlist[nfrom]arc.last]lsr := 0;
ignore_argument (opt[nopt], opt[nopt]arg);
elseif match_option (opt[nopt], "right"):
if known opt[nopt]arg:
vlist[nfrom]arc[vlist[nfrom]arc.last]lsr
:= scantokens (opt[nopt]arg);
else:
vlist[nfrom]arc[vlist[nfrom]arc.last]lsr := 1;
fi
% \end{macrocode}
% Labels and which side they're on:
% \begin{macrocode}
elseif match_option (opt[nopt], "label"):
get_argument (opt[nopt], opt[nopt]arg,
vlist[nfrom]arc[vlist[nfrom]arc.last]lbl);
elseif match_option (opt[nopt], "label.side"):
get_argument (opt[nopt], opt[nopt]arg,
vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.side);
elseif match_option (opt[nopt], "label.dist"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.dist);
% \end{macrocode}
% Ignore bogus options:
% \begin{macrocode}
else:
ignore_option (opt[nopt], opt[nopt]arg);
fi
endfor
% \end{macrocode}
% Avoid entering invalid linestyles into the tables, because the
% delayed evaluation will make errors harder to find (line numbers
% will be wrong):
% \begin{macrocode}
if valid_style sty:
vlist[nfrom]arc[vlist[nfrom]arc.last]sty := sty;
else:
errhelp "feynmf: your linestyle is not recognizable, "
& "check spelling and reprocess!";
errmessage "feynmf: line style `" & sty & "' not known, "
& "replaced by `vanilla'";
vlist[nfrom]arc[vlist[nfrom]arc.last]sty := "vanilla";
fi
fi
% \end{macrocode}
% Restart the loop:
% \begin{macrocode}
nfrom := nto;
endfor
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef get_argument (expr opt, arg) (suffix variable) =
if known arg:
variable := arg;
else:
message "feynmf: option `" & opt & "' needs an argument. Ignored.";
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef ignore_argument (expr opt, arg) =
if known arg:
message "feynmf: option `" & opt & "' doesn't take an argument. "
& "Argument `" & arg & "' ignored.";
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef ignore_option (expr opt, arg)=
if known arg:
message "feynmf: ignoring option " & opt & "=" & arg & ".";
else:
message "feynmf: ignoring option " & opt & ".";
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmf}
% Since |vconnect| wil be the most frequent macro, we give it the
% shortest \TeX{} command sequence:
% \begin{macrocode}
%<style>\def\fmf#1#2{\fmfcmd{vconnect ("#1", #2);}}
% \end{macrocode}
% \end{macro}
% \begin{macrocode}
%<*base>
vardef vcyclen (expr sty) (suffix v) (expr n) =
for $ = 1 upto n - 1:
vconnect (sty, v[$], v[$+1]);
endfor
vconnect (sty, v[n], v[1]);
enddef;
% \end{macrocode}
% And the reverse:
% \begin{macrocode}
vardef vrcyclen (expr sty) (suffix v) (expr n) =
vconnect (sty, v[1], v[n]);
for $ = n downto 2:
vconnect (sty, v[$], v[$-1]);
endfor
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmfcyclen}
% \begin{macrocode}
%<style>\def\fmfcyclen#1#2#3{\fmfcmd{vcyclen ("#1", #2, #3);}}
%<style>\def\fmfrcyclen#1#2#3{\fmfcmd{vrcyclen ("#1", #2, #3);}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\fmfforce}
% \begin{macro}{\fmfshift}
% Explicit placement and shifting of vertices is handled in \TeX{} with
% \begin{macrocode}
%<style>\def\fmfforce#1#2{\fmfcmd{vforce ((#1),#2);}}
%<style>\def\fmfshift#1#2{\fmfcmd{vshift((#1),#2);}}
% \end{macrocode}
% \end{macro}
% \end{macro}
% Force the vertex |v| to be placed at position |z|:
% \begin{macrocode}
%<*base>
vardef vforce (expr z) (suffix v) =
venter v;
vlist[vlookup v]loc := z;
enddef;
% \end{macrocode}
% Shift the vertex |v| by |z|:
% \begin{macrocode}
vardef vshift (expr z) (text vl) =
forsuffixes $=vl:
if vexists $:
vlist[vlookup $]loc := vlist[vlookup $]loc + z;
fi
endfor
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmffixed}
% \changes{1.9}{1995/01/07}{New command: \texttt{fmffixed}.}
% Place the first two arguments in the distance given by the third
% argument.
% \begin{macrocode}
%<style>\def\fmffixed#1#2{\fmfcmd{vconstraint ((#1), #2);}}
% \end{macrocode}
% \end{macro}
% This amounts to adding one or more constraints into the vertex data
% structure:
% \begin{macrocode}
%<*base>
vardef vconstraint (expr z) (text vl) =
save nfrom, nto;
numeric nfrom, nto;
forsuffixes to = vl:
venter to;
nto := vlookup to;
if known nfrom:
vlist[nfrom]constr.last := vlist[nfrom]constr.last + 1;
vlist[nto]constr.last := vlist[nto]constr.last + 1;
vlist[nfrom]constr[vlist[nfrom]constr.last] := nto;
vlist[nto]constr[vlist[nto]constr.last] := nfrom;
vlist[nto]loc = vlist[nfrom]loc + z;
fi
nfrom := nto;
endfor
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmflabel}
% \begin{macrocode}
%<style>\def\fmflabel#1#2{\fmfcmd{vlabel ("#1", #2);}}
% \end{macrocode}
% \end{macro}
% \begin{macrocode}
%<*base>
vardef vlabel (expr s) (suffix v) =
venter v;
vlist[vlookup v]lbl := s;
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmfv}
% \begin{macrocode}
%<style>\def\fmfv#1#2{\fmfcmd{vvertex ("#1", #2);}}
%<style>\def\fmfvn#1#2#3{\fmfcmd{vvertexn ("#1", #2, #3);}}
% \end{macrocode}
% \end{macro}
% \changes{1.7}{1994/10/22}{%
% \texttt{blob} and \texttt{dot} options obsolete, handle generalized
% decorations (polygons).}
% \begin{macrocode}
%<*base>
vardef vvertex (expr vtxsty) (text vl) =
save nopt, sty, arg;
numeric nopt, arg;
string sty;
getopt (opt, vtxsty);
forsuffixes v = vl:
venter v;
n := vlookup v;
for nopt = opt.first upto opt.last:
if match_option (opt[nopt], "label"):
get_argument (opt[nopt], opt[nopt]arg, vlist[n]lbl);
elseif match_option (opt[nopt], "label.angle"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[n]lbl.ang);
elseif match_option (opt[nopt], "label.dist"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[n]lbl.dist);
elseif match_option (opt[nopt], "decoration.shape"):
if known opt[nopt]arg:
% \end{macrocode}
% Maybe we should replace the following long switch by a hashing
% scheme.
% \begin{macrocode}
if match_prefix (opt[nopt]arg, "circle"):
vlist[n]decor.shape := fullcircle;
elseif match_prefix (opt[nopt]arg, "square"):
vlist[n]decor.shape := unitsquare shifted -(.5,.5);
elseif match_prefix (opt[nopt]arg, "triangle"):
vlist[n]decor.shape := polygon 3;
elseif match_prefix (opt[nopt]arg, "triagon"):
vlist[n]decor.shape := polygon 3;
elseif match_prefix (opt[nopt]arg, "diamond"):
vlist[n]decor.shape := polygon 4;
elseif match_prefix (opt[nopt]arg, "tetragon"):
vlist[n]decor.shape := polygon 4;
elseif match_prefix (opt[nopt]arg, "pentagon"):
vlist[n]decor.shape := polygon 5;
elseif match_prefix (opt[nopt]arg, "hexagon"):
vlist[n]decor.shape := polygon 6;
elseif match_prefix (opt[nopt]arg, "triagram"):
vlist[n]decor.shape := polygram 3;
elseif match_prefix (opt[nopt]arg, "tetragram"):
vlist[n]decor.shape := polygram 4;
elseif match_prefix (opt[nopt]arg, "pentagram"):
vlist[n]decor.shape := polygram 5;
elseif match_prefix (opt[nopt]arg, "hexagram"):
vlist[n]decor.shape := polygram 6;
else:
if feynmfwizard:
vlist[n]decor.shape := scantokens(opt[nopt]arg);
else:
message "feynmf: invalid argument `" & opt[nopt]arg
& "' to option `decor.shape'. Ignored.";
fi
fi
else:
message "feynmf: option `decor.shape' needs an argument. Ignored.";
fi
% \end{macrocode}
% \MP{} has |filled| reserved, use |sty| instead.
% \begin{macrocode}
elseif match_option (opt[nopt], "decoration.filled"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[n]decor.sty);
elseif match_option (opt[nopt], "decoration.size"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[n]decor.size);
elseif match_option (opt[nopt], "decoration.angle"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[n]decor.ang);
% \end{macrocode}
% Ignore bogus options:
% \begin{macrocode}
else:
ignore_option (opt[nopt], opt[nopt]arg);
fi
endfor
endfor
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef vvertexn (expr vtxsty) (suffix v) (expr n) =
vvertex (vtxsty, vmklist (v, n));
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmfblob}
% \begin{macro}{\fmfdot}
% We can decorate vertices with ``blobs'' and dots from \TeX{} with
% the command sequences:
% \begin{macrocode}
%<style>\def\fmfblob#1#2{\fmfcmd{vblob ((#1),#2);}}
%<style>\def\fmfdot#1{\fmfcmd{vdot (#1);}}
% \end{macrocode}
% \end{macro}
% \end{macro}
% The vertices in the list |vl| will be drawn with a blob of diameter
% |bd|:
% \begin{macrocode}
%<*base>
vardef vblob (expr bd) (text vl)=
forsuffixes $=vl:
if not vexists $: venter $; fi
vlist[vlookup $]decor.shape := fullcircle;
vlist[vlookup $]decor.size := bd;
vlist[vlookup $]decor.sty := .5;
endfor
enddef;
% \end{macrocode}
% The vertices in the list |vl| will be drawn with a dot.
% \begin{macrocode}
vardef vdot (text vl)=
forsuffixes $=vl:
if not vexists $: venter $; fi
vlist[vlookup $]decor.shape := fullcircle;
vlist[vlookup $]decor.size := dot_size;
vlist[vlookup $]decor.sty := 1;
endfor
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef vdotn (suffix v) (expr n) =
vdot (vmklist (v, n));
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef vblobn (suffix v) (expr n) =
vblob (vmklist (v, n));
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmfdotn}
% Place |#2| blobs or dots at $|v|_1,\ldots,|v|_{|#1|}$.
% \begin{macrocode}
%<style>\def\fmfblobn#1#2{\fmfcmd{vblobn (#1, #2);}}
%<style>\def\fmfdotn#1#2{\fmfcmd{vdotn (#1, #2);}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\fmfleft}
% \begin{macro}{\fmfright}
% \begin{macro}{\fmfbottom}
% \begin{macro}{\fmftop}
% \begin{macro}{\fmfsurround}
% External vertices are positioned thusly in \TeX{}:
% \changes{1.9}{1994/10/27}{%
% Make \texttt{fmfincoming} and \texttt{fmfoutgoing} obsolescent.
% Provide \texttt{fmfleft}, \texttt{fmfright}, \texttt{fmfbottom}
% and \texttt{fmftop} instead.}
% \changes{1.9}{1994/12/29}{Fix typos in \texttt{fmfbottom}
% and \texttt{fmftop}.}
% \begin{macrocode}
%<*style>
\def\fmfleft#1{\fmfcmd{vleft(#1);}}
\def\fmfright#1{\fmfcmd{vright(#1);}}
\def\fmfbottom#1{\fmfcmd{vbottom(#1);}}
\def\fmftop#1{\fmfcmd{vtop(#1);}}
\let\fmfincoming\fmfleft
\let\fmfoutgoing\fmfright
\def\fmfsurround#1{\fmfcmd{vsurround(#1);}}
%</style>
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% Here are the ``galleries'' we're hooking our external vertices on
% (see also the pictures on page~\pageref{p:galleries}):
% \begin{macrocode}
%<*base>
vardef left_gallery = (.1w,0)..(0,.5h)..(.1w,h) enddef;
vardef right_gallery = (.9w,0)..(w,.5h)..(.9w,h) enddef;
vardef bottom_gallery = (0,.1h)..(.5w,0)..(w,.1h) enddef;
vardef top_gallery = (0,.9h)..(.5w,h)..(w,.9h) enddef;
vardef surround_gallery =
superellipse ((w,.5h), (.5w,h), (0,.5h), (.5w,0), .75)
enddef;
% \end{macrocode}
% and the \MF{} code which does the hard work for the above
% \TeX{} macros
% \begin{macrocode}
vardef vleft (text vl) = vdistribute (left_gallery, vl) enddef;
vardef vright (text vl) = vdistribute (right_gallery, vl) enddef;
vardef vbottom (text vl) = vdistribute (bottom_gallery, vl) enddef;
vardef vtop (text vl) = vdistribute (top_gallery, vl) enddef;
vardef vsurround (text vl) = vdistribute (surround_gallery, vl) enddef;
% \end{macrocode}
% Distribute the vertices in the list |vl| evenly along the path |p|:
% \begin{macrocode}
vardef vdistribute (expr p) (text vl) =
save numv, len, off;
numeric numv, len, off;
numv = count (vl);
% \end{macrocode}
% If the path is cyclic, place the first vertex twice:
% \begin{macrocode}
if cycle p: numv := numv + 1; fi
len := length (p);
if numv = 1:
vforce (point len/2 of p, vl);
else:
off := 0;
forsuffixes $ = vl:
vforce (point off of p, $);
off := off + len/(numv-1);
endfor
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmfleftn}
% \begin{macro}{\fmfrightn}
% \begin{macro}{\fmfbottomn}
% \begin{macro}{\fmftopn}
% \begin{macro}{\fmfsurroundn}
% A short cut:
% \begin{macrocode}
%<*style>
\def\fmfleftn#1#2{\fmfcmd{vleftn(#1,#2);}}
\def\fmfrightn#1#2{\fmfcmd{vrightn(#1,#2);}}
\def\fmfbottomn#1#2{\fmfcmd{vbottomn(#1,#2);}}
\def\fmftopn#1#2{\fmfcmd{vtopn(#1,#2);}}
\let\fmfincomingn\fmfleftn
\let\fmfoutgoingn\fmfrightn
\def\fmfsurroundn#1#2{\fmfcmd{vsurroundn(#1,#2);}}
%</style>
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \begin{macrocode}
%<*base>
def vmklist (suffix v) (expr n) =
for $ = 1 upto n-1: v[$], endfor v[n]
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef vleftn (suffix v) (expr n) =
vleft (vmklist (v, n));
enddef;
vardef vrightn (suffix v) (expr n) =
vright (vmklist (v, n));
enddef;
vardef vbottomn (suffix v) (expr n) =
vbottom (vmklist (v, n));
enddef;
vardef vtopn (suffix v) (expr n) =
vtop (vmklist (v, n));
enddef;
vardef vsurroundn (suffix v) (expr n) =
vsurround (vmklist (v, n));
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmffor}
% \begin{macro}{\endfmffor}
% \begin{macrocode}
%<*style>
\def\fmffor#1#2#3#4{\fmfcmd{for #1 = #2 step #3 until #4:}}
\def\endfmffor{\fmfcmd{endfor}}
%</style>
% \end{macrocode}
% \end{macro}
% \end{macro}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Choosing a Layout for the Graph}
% The procedure |vposition| is called near the end and
% chooses ``optimal'' vertex positions by minimizing the sum of the
% weighted lengths of the arcs. Since the quantity to be optimized is
% quadratic in the vertices
% \begin{equation}
% L = \frac{1}{2} \sum_i \sum_{j\in\alpha(i)}
% t_{ij} (\vec v_i - \vec v_j)^2\,,
% \end{equation}
% where~$\alpha(i)$ denotes the set of vertices connectes with the
% vertex~$i$, we just have to solve a system of linear equations.
% Adding Lagrange multipliers~$\lambda_{ij}$ for the constraints that
% have been specified
% \begin{equation}
% \Lambda = \sum_i \sum_{j\in\gamma(i) \atop j>i}
% \vec\lambda_{ij}\cdot(\vec v_i - \vec v_j - \vec d_{ij})\,,
% \end{equation}
% where~$\gamma(i)$ denotes the set of vertices which have a fixed
% distance to the vertex~$i$, the set of linear equations is given by
% \begin{eqnarray}
% 0 & = & \frac{\partial}{\partial \vec v_i} (L+\Lambda)
% = \sum_{j\in\alpha(i)} t_{ij} (\vec v_i - \vec v_j)
% + \sum_{j\in\gamma(i) \atop j>i} \vec\lambda_{ij}
% - \sum_{j\in\gamma(i) \atop j<i} \vec\lambda_{ji} \\
% 0 & = & \vec v_i - \vec v_j - \vec d_{ij}\;\; \mid j \in \gamma(i)\,.
% \end{eqnarray}
% The implementation is simple: loop over all vertices in |vlist[]|
% \begin{macrocode}
%<*base>
vardef vposition =
for i = vertices:
% \end{macrocode}
% and iff the position of the vertex has not been fixed yet, add
% another equation. Note that each arc enters twice (incoming
% \emph{and} outgoing) in this procedure. Thus it is easiest to store
% them \emph{both} ways in the |vlist| structure
% (cf.~page~\pageref{pg:vconnect})\label{pg:vposition}.
% \begin{macrocode}
if unknown vlist[i]loc:
origin = origin
for j = varcs (i):
+ vlist[i]arc[j]tns * (vlist[i]loc - vlist[vlist[i]arc[j]]loc)
endfor
for j = vconstr (i):
if i < vlist[i]constr[j]:
+ lambda[i][vlist[i]constr[j]]
else:
- lambda[vlist[i]constr[j]][i]
fi
endfor;
fi
endfor
% \end{macrocode}
% Inquiring minds might want to see the result in numbers:
% \begin{macrocode}
if vtracing: vdump; fi
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmfposition}
% Again, we can ask for positioning and drawing explicitely from \TeX
% (usually called implicitely by |\end{fmfchar}|). This is useful for
% subsequent fine tuning.
% \begin{macrocode}
%<style>\def\fmfposition{\fmfcmd{vposition;}}
% \end{macrocode}
% \end{macro}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Drawing the Graph}
% \begin{macro}{\fmfdraw}
% \begin{macrocode}
%<style>\def\fmfdraw{\fmfcmd{vdraw;}}
% \end{macrocode}
% \end{macro}
% And here's the actual \MF{} implementation of |vdraw|:
% \begin{macrocode}
%<*base>
vardef vdraw =
% \end{macrocode}
% Check that all vertices are known before attempting to draw the
% diagram.
% \begin{macrocode}
for i = vertices:
if not known vlist[i]loc:
errhelp "Your graph specification was not complete (probably a "
& "lone vertex). Check logic and reprocess!";
errmessage "feynmf: vertex `" & vlist[i]name & "' not determined, "
& "replaced by `(0,0)'.";
vlist[i]loc := origin;
fi
if unknown vlist[i]decor.size:
vlist[i]decor.size = decor_size;
fi
endfor
% \end{macrocode}
% Now do the actual drawing, looping over vertices and arcs.
% \begin{macrocode}
for i = vertices:
for j = varcs (i):
if known vlist[i]arc[j]sty:
% \end{macrocode}
% \changes{1.5}{1994/10/20}{Implement optional argument for detours.}
% \begin{macrocode}
vdraw_arc (vlist[i]arc[j]sty,
cut_decors (vlist[i],
vbuild_arc (vlist[i]arc[j]lsr,
vlist[i]loc,
vlist[vlist[i]arc[j]]loc),
vlist[vlist[i]arc[j]]),
vlist[i]arc[j]lbl);
fi
endfor;
vdraw_vertex_label vlist[i];
vdraw_vertex vlist[i];
endfor
enddef;
% \end{macrocode}
% Construct an arc from |from| to |to|. The arc will be straight if
% $|lsr| = 0$, a left (approximate) halfcircle if $|lsr| = -1$ and a
% right halfcircle if $|lsr| = 1$. Othe values of |lsr| will give
% obvious interpolations. We optimize the most frequent straight
% line case.
% \changes{1.6}{1994/10/22}{%
% Don't use \texttt{interpath} and halfcircles for detours anymore.
% Simple paths constructed from three points are better (and
% simpler).}
% \begin{macrocode}
vardef vbuild_arc (expr lsr, from, to) =
if lsr = 0:
from -- to
else:
from
.. (1-lsr)/2 *(to rotatedabout (.5[from,to], 90))
+ (1+lsr)/2 * (to rotatedabout (.5[from,to], -90))
.. to
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef vdraw_arc (expr sty, arc) (suffix lbl) =
scantokens ("draw_" & sty) (arc);
vdraw_arc_label (arc, lbl);
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef vdraw_arc_label (expr arc) (suffix lbl) =
if lbl <> "":
save _a, _z, _zz, _r;
numeric _a;
pair _z, _zz, _r;
_z := point .5 length (arc) of arc;
_r := direction .5 length (arc) of arc rotated - 90;
if lbl.side = "left":
_a := angle (-_r);
elseif lbl.side = "right":
_a := angle (_r);
else:
% \end{macrocode}
% Normalize to avoid overflow in |dotprod|:
% \changes{1.9}{1995/02/18}{%
% \texttt{vdraw\_arc\_label}: Protect against divide by zero.}
% \begin{macrocode}
_zz = _z - .5[point 0 of arc, point infinity of arc];
if ((_zz if length (_zz) > 0: / length (_zz) fi)
dotprod _r) >= 0:
_a := angle (_r);
else:
_a := angle (-_r);
fi
fi
LaTeX_text (_z + lbl.dist * thick * dir _a, _a, lbl);
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef vdraw_vertex_label suffix v =
if v.lbl <> "":
save a;
numeric a;
if unknown v.lbl.ang:
if v.loc = (.5w,.5h):
a := 0;
else:
a := angle (v.loc - (.5w,.5h));
fi
else:
a := v.lbl.ang;
fi
LaTeX_text (v.loc + v.lbl.dist * thick * dir a, a, v.lbl);
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef vdraw_vertex suffix v =
save cmd;
string cmd;
if known v.decor.shape:
cmd := "filldraw";
if known v.decor.sty:
if v.decor.sty = 0:
cmd := "draw";
elseif abs (v.decor.sty) >= 1:
cmd := "filldraw";
elseif v.decor.sty > 0:
cmd := "shadedraw";
else:
cmd := "hatchdraw";
fi
fi
scantokens (cmd) v.decor.shape
if known v.decor.ang: rotated v.decor.ang fi
scaled v.decor.size shifted v.loc;
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef polygon expr n =
if n > 2:
for i = 1 upto n:
(.5up rotated (360i/n)) --
endfor
cycle
else:
fullcircle
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef polygram expr n =
if n > 2:
for i = 1 upto n:
(.5up rotated (360i/n)) --
(.2up rotated (360(i+.5)/n)) --
endfor
cycle
else:
fullcircle
enddef;
% \end{macrocode}
% Unfortunately, enclosing the |message| in a |batchmode|
% |errorstopmode| pair doesn't work. The label information isn't
% written to the terminal, but an empty line is anyway \ldots
% \changes{1.4}{1994/05/28}{%
% \MP: \texttt{write} the label files directly.}
% \begin{macrocode}
vardef LaTeX expr text =
%<*!mp>
message (":" & jobname & "." & decimal charcode & ":" & text & "%%%")
%</!mp>
%<*mp>
if LaTeX_file = "":
LaTeX_file := jobname & ".t" & decimal charcode;
write ("% " & LaTeX_file & " -- generated from " & jobname & ".mp")
to LaTeX_file;
write (text & "%%%") to LaTeX_file
%</mp>
enddef;
vardef LaTeX_text (expr z, a, txt) =
LaTeX "\fmfL(" & (decimal (xpart z/LaTeX_unitlength)) & ","
& (decimal (ypart z/LaTeX_unitlength)) & ","
& (voctant a) & "){" & txt & "}";
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmfL}
% This is an internal macro for squeezing more text into \MF's
% 80 character wide output.
% \begin{macrocode}
%<style>\def\fmfL(#1,#2,#3)#4{\put(#1,#2){\makebox(0,0)[#3]{#4}}}
% \end{macrocode}
% \end{macro}
% This will only be used with $\vert|a|\vert\le180$:
% \begin{macrocode}
%<*base>
vardef voctant expr a =
voctant_list[floor (a/45 + .5)]
enddef;
string voctant_list[];
voctant_list[-4] := "r";
voctant_list[-3] := "rt";
voctant_list[-2] := "t";
voctant_list[-1] := "lt";
voctant_list[0] := "l";
voctant_list[1] := "lb";
voctant_list[2] := "b";
voctant_list[3] := "rb";
voctant_list[4] := "r";
% \end{macrocode}
% \begin{macrocode}
vardef vdump =
message ">>>>> Vertices and arcs for diagram #" & decimal charcode
& " of " & jobname & ".mf:";
for i = vertices:
message "> " & vlist[i]name & "=" & decimal_pair (vlist[i]loc)
& ": #lines="
& decimal (vlist[i]arc.last - vlist[i]arc.first + 1)
if vlist[i]lbl <> "":
& ", lbl=" & vlist[i]lbl
& ", l.angle=" & decimal_ (vlist[i]lbl.ang)
& ", l.dist=" & decimal_ (vlist[i]lbl.dist)
fi
& ".";
endfor
for i = vertices:
for j = varcs (i):
if known vlist[i]arc[j]sty:
message "> " & vlist[i]name & "*" & vlist[vlist[i]arc[j]]name
& ": " & vlist[i]arc[j]sty
& ", tns=" & decimal_ (vlist[i]arc[j]tns)
& ", lsr=" & decimal_ (vlist[i]arc[j]lsr)
if vlist[i]arc[j]lbl <> "":
& ", lbl=" & vlist[i]arc[j]lbl
& ", l.side=" & vlist[i]arc[j]lbl.side
& ", l.dist=" & decimal_ (vlist[i]arc[j]lbl.dist)
fi
& ".";
fi
endfor
for j = vconstr (i):
if i < vlist[i]constr[j]:
% \end{macrocode}
% We don't keep an explicit record of the fixed distances, but they're
% easy to recover:
% \begin{macrocode}
save z;
pair z;
z = vlist[vlist[i]constr[j]]loc - vlist[i]loc;
message "> " & vlist[i]name & "&"
& vlist[vlist[i]constr[j]]name
& ": " & decimal_pair (z);
fi
endfor;
endfor
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef decimal_ (text n) =
if known n: decimal n else: "?" fi
enddef;
% \end{macrocode}
% \begin{macrocode}
vardef decimal_pair (text z) =
"(" & decimal_ (xpart z) & "," & decimal_ (ypart z) & ")"
enddef;
% \end{macrocode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Online displays}
% This is a bit smarter about pictures of varying sizes and some
% overshooting than |showit|. You can still get burned, though,
% because \MF{} might not be able to enlarge the screen sufficiently.
% \changes{1.9}{1994/10/25}{Online display support.}
% \begin{macrocode}
def show_diagram_ expr frame =
if (screen_cols < w + 2 xpart frame) or (screen_rows < h + 2 ypart frame):
screen_cols := w + 2 xpart frame;
screen_rows := h + 2 ypart frame;
openwindow currentwindow
from origin to (screen_rows, screen_cols)
at (- xpart frame, h + ypart frame);
showit_;
if showstopping > 0:
stop "This is diagram #" & decimal charcode
& ". Hit return to continue...";
enddef;
% \end{macrocode}
% Self-modifying code is \emph{fun}: make sure to clear the window the
% second time around.
% \begin{macrocode}
def show_diagram =
def show_diagram =
display blankpicture inwindow currentwindow;
show_diagram_
enddef;
show_diagram_
enddef;
% \end{macrocode}
% |show_all_diagrams| turns on the above online display mechanism.
% Creative use of |extra_endchar| allows us to do this from the
% command line (|showstopping| is used here to slow down the slide
% show).
% \begin{verbatim}
% mf '\mode:=localmode;
% showstopping:=1;
% extra_endchar:="show_all_diagrams(100,100);";
% input foo.mf'
% \end{verbatim}
% \begin{macrocode}
def show_all_diagrams expr frame =
def showit = show_diagram frame enddef;
displaying:=1;
enddef;
%</base>
% \end{macrocode}
% \begin{macro}{\fmfdisplay}
% Make the display accessible from \TeX{} too.
% \begin{macrocode}
%<*style>
\def\fmfdisplay{\fmfcmd{show_all_diagrams (100,100);}}
\def\fmfstopdisplay{\fmfcmd{showstopping:=1;}\fmfdisplay}
%</style>
% \end{macrocode}
% \end{macro}
% Now we're done with the \MF{} macros
% \begin{macrocode}
%<*base>
endinput;
%</base>
% \end{macrocode}
% and the \TeX{} macros too:
% \begin{macrocode}
%<*style>
\mdqrestore
%</style>
% \end{macrocode}
% \Finale
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \appendix
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Driver file}
% \begin{macrocode}
%<*driver>
%<*!209>
\documentclass[a4paper]{article}
\usepackage{doc}
% \end{macrocode}
% The \MF{} and \MP{} logos come out much nicer if you have |mflogo|
% installed:
% \begin{macrocode}
\IfFileExists{mflogo.sty}%
{\usepackage{mflogo}%
\def\FMF{\texttt{feyn}\textlogo{MF}}}%
{\def\MF{\textsf{META}\-\textsf{FONT}}%
\def\MP{\textsf{META}\-\textsf{POST}}%
\def\FMF{\texttt{feyn}\textsf{MF}}}
% \end{macrocode}
% Here is the place to declare your own PostScript aware |dvi| driver
% option:
% \begin{macrocode}
%<mp>\usepackage[dvips]{feynmp}
%<!mp>\usepackage{feynmf}
%</!209>
%<*209>
%<mp>\documentstyle[doc,feynmp209]{article}
%<!mp>\documentstyle[doc,feynmf209]{article}
\def\textit#1{{\it#1\/}}
\def\textbf#1{{\bf#1}}
\def\textsf#1{{\sf#1}}
\def\texttt#1{{\tt#1}}
\def\emph#1{{\em#1\/}}
\let\bfseries\bf
\def\LaTeXe{\LaTeX$2_\epsilon$}
\def\MF{\textsf{META}\-\textsf{FONT}}
\def\MP{\textsf{META}\-\textsf{POST}}
\def\FMF{\texttt{feyn}\textsf{MF}}
%</209>
\font\manfnt=manfnt
\def\dangerousbend/{{\manfnt\char"7F}}
\def\dubious{\begin{itemize}\item[\dangerousbend/]}
\def\enddubious{\end{itemize}}
\parindent0pt
%<manual>\OnlyDescription
\EnableCrossrefs
\RecordChanges
\CodelineIndex
\DoNotIndex{\def,\gdef,\long,\let,\begin,\end,\if,\ifx,\else,\fi}
\DoNotIndex{\immediate,\write,\newwrite,\openout,\closeout,\typeout}
\DoNotIndex{\font,\nullfont,\jobname,\documentclass}
\DoNotIndex{\batchmode,\errorstopmode,\char,\catcode,\ }
\DoNotIndex{\CodelineIndex,\docdate,\DocInput,\DoNotIndex,\EnableCrossrefs}
\DoNotIndex{\filedate,\filename,\fileversion,\logo,\manfnt}
\DoNotIndex{\NeedsTeXFormat,\ProvidesPackage,\RecordChanges,\space}
\DoNotIndex{\usepackage,\wlog,\@gobble,\@ifundefined,\@namedef,\@spaces}
\DoNotIndex{\begingroup,\csname,\edef,\endcsname,\expandafter,\hbox}
\DoNotIndex{\hskip,\ifeof,\ignorespaces,\item,\leavevmode,\loop,\makebox}
\DoNotIndex{\newcounter,\newif,\newread,\openin,\par,\parindent,\put}
\DoNotIndex{\read,\relax,\repeat,\setcounter,\stepcounter,\the}
\DoNotIndex{\value,\vbox,\vskip}
\DoNotIndex{}
% \end{macrocode}
% Cut the linebreaking some slack for macrocode which might conatin
% long lines (it doesn't really hurt if they stick out a bit).
% \begin{macrocode}
\let\origmacrocode\macrocode
\def\macrocode{\hfuzz 5em\origmacrocode}
\begin{document}
\DocInput{feynmf.dtx}
\end{document}
%</driver>
% \end{macrocode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\endinput
Local Variables:
mode:LaTeX
fill-prefix:"% "
indent-tabs-mode:nil
change-log-default-name:"TODO"
page-delimiter:"^% %%%%%%%%%*\n"